I am making a note-saving app using Firebase Firestore and a RecyclerView.
So far users are able to enter the title and content of the note, this saves and works fine.
What I would like to add is the current date (in a "dd/MM/yy" format) when the user saves the note to be displayed in the recycler view the notes are displayed in.
My code for adding the note is as follows
public class AddWellbeingActivity extends AppCompatActivity {
private static final String TAG = "AddWellbeingActivity";
EditText createtitleofnote, createcontentofnote;
FloatingActionButton savenote;
FirebaseAuth firebaseAuth;
FirebaseUser firebaseUser;
FirebaseFirestore firebaseFirestore;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_wellbeing);
savenote = findViewById(R.id.saveNote);
createcontentofnote = findViewById(R.id.createContentNote);
createtitleofnote = findViewById(R.id.createTitleNote);
firebaseAuth = FirebaseAuth.getInstance();
firebaseFirestore = FirebaseFirestore.getInstance();
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
savenote.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String title = createtitleofnote.getText().toString();
String content = createcontentofnote.getText().toString();
if(title.isEmpty() || content.isEmpty())
{
Toast.makeText(getApplicationContext(), "Both fields are Required", Toast.LENGTH_SHORT).show();
}
else
{
DocumentReference documentReference = firebaseFirestore.collection("notes").document(firebaseUser.getUid()).collection("myNotes").document();
Map<String, Object> note = new HashMap<>();
note.put("title",title);
note.put("content", content);
documentReference.set(note).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid)
{
Toast.makeText(getApplicationContext(), "Wellbeing entry saved", Toast.LENGTH_SHORT).show();
startActivity(new Intent(AddWellbeingActivity.this, WellbeingActivity.class));
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e)
{
Toast.makeText(getApplicationContext(), "Wellbeing entry failed to save", Toast.LENGTH_SHORT).show();
}
});
}
}
});
}
If anyone has a solution it would be greatly appreciated
To add a timestamp field when add a note into Firestore, then you should add an extra put() call:
note.put("title",title);
note.put("content", content);
note.put("date", FieldValue.serverTimestamp()); 👈
Related
I am trying to create a register activity to allow a user to register however I keep getting the error:
Cannot resolve method 'setTimestampsInSnapshotsEnabled' in 'Builder'"
It's only the section which has the setTimestampsInSnapshotsEnabled that is giving me the issue. Do I need an implementation?
Here is my Java code:
public class RegisterActivity extends AppCompatActivity implements View.OnClickListener
{
private static final String TAG = "RegisterActivity";
//widgets
private EditText mEmail, mPassword, mConfirmPassword;
private ProgressBar mProgressBar;
//vars
private FirebaseFirestore mDb;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
mEmail = (EditText) findViewById(R.id.input_email);
mPassword = (EditText) findViewById(R.id.input_password);
mConfirmPassword = (EditText) findViewById(R.id.input_confirm_password);
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
findViewById(R.id.btn_register).setOnClickListener(this);
mDb = FirebaseFirestore.getInstance();
hideSoftKeyboard();
}
/**
* Register a new email and password to Firebase Authentication
* #param email
* #param password
*/
public void registerNewEmail(final String email, String password){
showDialog();
FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Log.d(TAG, "createUserWithEmail:onComplete:" + task.isSuccessful());
if (task.isSuccessful()){
Log.d(TAG, "onComplete: AuthState: " + FirebaseAuth.getInstance().getCurrentUser().getUid());
//insert some default data
User user = new User();
user.setEmail(email);
user.setUsername(email.substring(0, email.indexOf("#")));
user.setUser_id(FirebaseAuth.getInstance().getUid());
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
.setTimestampsInSnapshotsEnabled(true)
.build();
mDb.setFirestoreSettings(settings);
FirebaseFirestoreSettings newUserRef = mDb
.collection(getString(R.string.collection_users))
.document(FirebaseAuth.getInstance().getUid());
newUserRef.set(user).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
hideDialog();
if(task.isSuccessful()){
redirectLoginScreen();
}else{
View parentLayout = findViewById(android.R.id.content);
Snackbar.make(parentLayout, "Something went wrong.", Snackbar.LENGTH_SHORT).show();
}
}
});
}
else {
View parentLayout = findViewById(android.R.id.content);
Snackbar.make(parentLayout, "Something went wrong.", Snackbar.LENGTH_SHORT).show();
hideDialog();
}
// ...
}
});
}
/**
* Redirects the user to the login screen
*/
private void redirectLoginScreen(){
Log.d(TAG, "redirectLoginScreen: redirecting to login screen.");
Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
private void showDialog(){
mProgressBar.setVisibility(View.VISIBLE);
}
private void hideDialog(){
if(mProgressBar.getVisibility() == View.VISIBLE){
mProgressBar.setVisibility(View.INVISIBLE);
}
}
private void hideSoftKeyboard(){
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn_register:{
Log.d(TAG, "onClick: attempting to register.");
//check for null valued EditText fields
if(!isEmpty(mEmail.getText().toString())
&& !isEmpty(mPassword.getText().toString())
&& !isEmpty(mConfirmPassword.getText().toString())){
//check if passwords match
if(doStringsMatch(mPassword.getText().toString(), mConfirmPassword.getText().toString())){
//Initiate registration task
registerNewEmail(mEmail.getText().toString(), mPassword.getText().toString());
}else{
Toast.makeText(RegisterActivity.this, "Passwords do not Match", Toast.LENGTH_SHORT).show();
}
}else{
Toast.makeText(RegisterActivity.this, "You must fill out all the fields", Toast.LENGTH_SHORT).show();
}
break;
}
}
}
}
If I look at the current documentation for FirebaseFirestoreSettings.Builder, I don't see any setTimestampsInSnapshotsEnabled method. So that probably explains the error message: you're trying to call a method that doesn't exist.
My guess is that your code was meant for an older version of the SDK when the method did exist. Since it doesn't exist anymore now, you either have to use the version of the SDK that the code was made for, or remove the call.
Update: it looks like timestampsInSnapshotsEnabled was removed in version 22 of the Android SDK for Firestore back in October 2020.
Hi I want to implement clean architecture while using the realtime database but is seems that it is impossible to seperate the database from the my account screen class. Ideally I would want a DatabaseManager class that would handle all database operation (getting reading and posting to the db) but it seems that because the AuthStateChangeListener needs to be in the oncreate of my files it can't work. Does anyone know of any work-arounds? Here is the code I am using this on:
public class CreateAccountScreen extends AppCompatActivity {
private Button mRegister;
private EditText mEmail, mPassword, mCPassword, mName;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener firebaseAuthStateListener;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.create_account);
//------------------------------------------------------
//I would want to put this in a seperate class
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
//------------------------------------------------------
mAuth = FirebaseAuth.getInstance();
firebaseAuthStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user !=null){
Intent intent = new Intent(CreateAccountScreen.this, HomeScreen.class);
startActivity(intent);
finish();
return;
}
}
};
//-----------------------------------------------------
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//I would want this in a seperate class
//------------------------------------------------------
mRegister = (Button) findViewById(R.id.goSignIn2);
mEmail = (EditText) findViewById(R.id.username3);
mPassword = (EditText) findViewById(R.id.password2);
mCPassword = (EditText) findViewById(R.id.password3);
mName = (EditText) findViewById(R.id.username2);
mRegister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final String email = mEmail.getText().toString();
final String password = mPassword.getText().toString();
final String cPassword = mCPassword.getText().toString();
final String name = mName.getText().toString();
if (name.equals("") || password.equals("") || email.equals("") || !password.equals(cPassword)) {
Toast.makeText(CreateAccountScreen.this, "sign up error", Toast.LENGTH_SHORT).show();
return;
}
//------------------------------------------------------
//I would want to also put this in a seperate class
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
//------------------------------------------------------
//DatabaseManager.createUser(email, password, name, CreateAccountScreen.this);
mAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(CreateAccountScreen.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(!task.isSuccessful()) {
Toast.makeText(CreateAccountScreen.this, "sign up error", Toast.LENGTH_SHORT).show();
}else{
String userId = mAuth.getCurrentUser().getUid();
DatabaseReference currentUserDb = FirebaseDatabase.getInstance().getReference().child("Users").child(userId);
DatabaseReference currentUserDb2 = FirebaseDatabase.getInstance().getReference().child("Users").child(userId).child("connections").child("no").child(userId);
Map userInfo = new HashMap<>();
userInfo.put("name", name);
userInfo.put("profileImageUrl", "default");
currentUserDb2.setValue(true);
currentUserDb.updateChildren(userInfo);
}
}
});
//-----------------------------------------------------
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//I would want this in a seperate class
//------------------------------------------------------
}
});
}
}
When i try to go to the next activity by pressing the sign_up in the sign up page or log in in the log page when the user already exists, the app just exits and brings up an error.
Sign up Activity
// variable
final String TAG ="signUp";
private MaterialEditText edit_name;
private MaterialEditText edit_password;
//DECLARING & INITIALISING BUTTON TO SIGN UP
FButton sign_Up;
final String KEY_NAME = "name";
final String KEY_PASSWORD ="password";
final String KEY_MARKS ="marks";
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private DocumentReference user_reference = db.document("Users/Users details");
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.sign_up);
//INITIALISING THE EDITTEXT VIEWS
edit_name = findViewById(R.id.editName);
edit_password = findViewById(R.id.editPassword);
sign_Up = findViewById(R.id.btn_signUp);
sign_Up.setOnClickListener(view ->
{
user_reference.get()
.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>()
{
Map<String, Object> users = new HashMap<>();
String name = edit_name.getText().toString();
String password = edit_password.getText().toString();
#Override
public void onSuccess(DocumentSnapshot documentSnapshot)
{
if(documentSnapshot.exists())
{ // GETTING INFORMATION FROM FIRESTORE DATABASE
name = documentSnapshot.getString(KEY_NAME);
password = documentSnapshot.getString(KEY_PASSWORD);
Toast.makeText(sign_up.this, "This user already exist, Try again", Toast.LENGTH_LONG).show();
}
else
{
users.put(KEY_NAME,name);
users.put(KEY_PASSWORD, password);
db.collection("Users").document(name).set(users);
Toast.makeText(sign_up.this,"Registered",Toast.LENGTH_LONG).show();
Intent i = new Intent(sign_up.this,sum_selection.class);
startActivity(i);
}
}// END OF ONSUCCESS
})
.addOnFailureListener(new OnFailureListener()
{
#Override
public void onFailure(#NonNull Exception e)
{
Toast.makeText(sign_up.this, "Error",Toast.LENGTH_LONG).show();
Log.d(TAG,e.toString());
}
});
Log in Activity
private MaterialEditText user_name;
private MaterialEditText user_password;
FButton sign_in;
private FirebaseFirestore database = FirebaseFirestore.getInstance();
private DocumentReference user_reference = database.document("Users/users details");
final String KEY_NAME = "name";
final String KEY_PASSWORD = "password";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
sign_in = findViewById(R.id.btn_sign_in);
sign_in.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view) // log in button
{
user_reference.get()
.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>()
{
#Override
public void onSuccess(DocumentSnapshot documentSnapshot)
{
if(documentSnapshot.exists())
{
Toast.makeText(log_in.this,"Welcome"+ user_name, Toast.LENGTH_LONG).show();
// ADD INTENT TO GO TO THE SUM_SELECTION PAGE
Intent in = new Intent(log_in.this, sum_selection.class);
startActivity(in);
}
else
{
// DISPLAY ERROR MESSAGE TO USER
Toast.makeText(log_in.this, "User does not exist", Toast.LENGTH_LONG).show();
}
}
})
.addOnFailureListener(new OnFailureListener()
{
#Override
public void onFailure(#NonNull Exception e)
{
Log.d(TAG, e.toString());
}
}); ```
[Error message][1]
[1]: https://i.stack.imgur.com/8gR62.png
Intent i = new Intent((this/activity),LoginActivity.class);
(this/activity).startActivity(i);
Check your intent properly, Intent take current activity as the first param and the activity you want to load up as the second param. Also, call startActivity(i) from the activity context becuase currently you are under the context of Firebase Listener.
Also, post the error log.
i am working on a school project and i am using firebase authentication with email and password. i have a problem when a user sing in, then returns to the sing in page and tries to create a new account. when clicking the submit button to create his new account instead of going back to the sign in page, it goes to the users main page. this only happens if a user has already singed in and then tries to sign up another account. i have tried signin out the user when he is returning to the sign in page but it didnt work. here is my code:
sign in page:
public class SignIn extends AppCompatActivity {
EditText email,pass;
private FirebaseAuth mAuth;
FirebaseUser user;
FirebaseDatabase db;
DatabaseReference mRef;
String type,name;
public ProgressDialog pd;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_in);
mAuth = FirebaseAuth.getInstance();
email = findViewById(R.id.inpSigninEmail);
pass = findViewById(R.id.inpSigninPass);
db.getInstance();
mRef = FirebaseDatabase.getInstance().getReference().child("Users/");
type=null;
name=null;
context=this;
Log.e("asd","Loginoncreate");
}
public void signIn (View view){
if (email.getText().toString().trim().length() < 1 || pass.getText().toString().trim().length() < 1){
Toast.makeText(getApplicationContext(), "Please fill your information.", Toast.LENGTH_LONG).show();
}else{
pd = new ProgressDialog(this);
pd.setMessage("Signing in...");
pd.show();
mAuth.signInWithEmailAndPassword(email.getText().toString(), pass.getText().toString()).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
user = mAuth.getCurrentUser();
mRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
while (type==null){
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
type = String.valueOf(dataSnapshot.child(user.getUid()).child("/Type").getValue());
if (type!="null"){
break;
}
}
}
while (name==null){
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
name = String.valueOf(dataSnapshot.child(user.getUid()).child("/Name").getValue());
if (name!="null"){
break;
}
}
}
pd.dismiss();
if (type.matches("user")){
Intent intent = new Intent(context, UserMain.class);
intent.putExtra("name", name);
type=null;
name=null;
startActivity(intent);
finish();
Log.e("as","loginUser");
}else{
Intent intent = new Intent(context, CompanyMain.class);
intent.putExtra("name", name);
startActivity(intent);
finish();
type=null;
name=null;
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
pd.dismiss();
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}else{
pd.dismiss();
Toast.makeText(getApplicationContext(), task.getException().getMessage(),Toast.LENGTH_LONG).show();
}
}
});
}
}
public void signUp (View view){
startActivity(new Intent(SignIn.this, SignUp.class));
finish();
}
}
sign up page:
public class SignUp extends AppCompatActivity {
EditText name,email,pass;
private FirebaseAuth mAuth;
FirebaseDatabase db;
FirebaseUser user;
RadioButton Rbtn;
RadioGroup Rgroup;
DatabaseReference mRef;
boolean out = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_up);
mAuth = FirebaseAuth.getInstance();
name = findViewById(R.id.inpSignupName);
email = findViewById(R.id.inpSignupEmail);
pass = findViewById(R.id.inpSignupPass);
Rgroup = findViewById(R.id.radioGroup);
db = FirebaseDatabase.getInstance();
mRef = db.getReference("Users/");
Log.e("asd","Signuponcreate");
}
public void submit (View view){
if (name.getText().toString().trim().length() < 1 || email.getText().toString().trim().length() < 1 || pass.getText().toString().trim().length() < 1){
Toast.makeText(getApplicationContext(), "Please fill your information.", Toast.LENGTH_LONG).show();
}else{
mAuth.createUserWithEmailAndPassword(email.getText().toString() , pass.getText().toString()).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
Toast.makeText(getApplicationContext(),"Sign Up success!",Toast.LENGTH_LONG).show();
user = mAuth.getCurrentUser();
int radioId = Rgroup.getCheckedRadioButtonId();
Rbtn = findViewById(radioId);
if (Rbtn.getText().equals("User")){
mRef.child("/Normal").child(user.getUid()).child("/Name").setValue(name.getText().toString());
mRef.child("/Normal").child(user.getUid()).child("/Type").setValue("user");
}else{
mRef.child("/Company").child(user.getUid()).child("/Name").setValue(name.getText().toString());
mRef.child("/Company").child(user.getUid()).child("/Type").setValue("company");
}
startActivity(new Intent(SignUp.this, SignIn.class));
finish();
Log.e("as","signupUserGotoSignin");
}else{
Toast.makeText(getApplicationContext(), task.getException().getMessage(),Toast.LENGTH_LONG).show();
}
}
});
}
}
}
and here are my logs:
E/asd: Loginoncreate (this is the first message i see and its when i start up the app,then i sign in and go to user main page)
E/as: loginUser (when i sign in the first time while the is opened and go to users main page)
E/asd: Loginoncreate (When i return from the users main page)
E/asd: Signuponcreate (i go to create a new account)
E/as: signupUserGotoSignin (i create the account and want to return to the sign in page)
E/as: loginUser (here i would expect the Loginoncreate message again but i never get it, i always get this message 2 times. this message is onDataChanged)
E/as: loginUser
after i click the submit button to create the new account it never returns to the sign in page. i know that firebase is asynchronous but i dont know what i am doing wrong here. why the onCreate on sign in page never gets called and it goes immediately in the onDataChanged and takes me to the users main page?
I assume that signIn (View view) method is your signIn button click event. So,
firstly, you need to remove onClick attribute from button XML code.
android:onClick="signIn"
then, create onClick button event in onCreate() method.
Like,
Button button = findViewById(R.id.SignInbutton);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//put your signIn button all code here
}
});
The same thing does in the SignUp page activity.
Okay so i put everything i have inside the onDataChange under an If statement where i check temp variable if its true, and right before i am move the user to the users main page i make that variable false. this fixed my problem but if someone have an explanation on why this was happening before i would still appreciate it. thanks
i"m working on a project that contains a code like this one: How to add Document with Custom ID to firestore (Angular)
When I'm about to try the app, it always crashes. But the code is all the same.
The error that I get in the LogCat is this:
Invalid document reference. Document references must have an even number of segments, but Users has 1
My full code is this:
public class RegisterActivity extends AppCompatActivity {
private EditText registerUsername;
private EditText registerEmail;
private EditText registerPassword;
private EditText registerConfirmPassword;
private Button registerRegisterButton;
private Button registerLoginButton;
private ProgressBar registerProgressBar;
private FirebaseFirestore firebaseFirestore;
private String user_id;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
registerUsername = findViewById(R.id.register_username);
registerEmail = findViewById(R.id.register_email);
registerPassword = findViewById(R.id.register_password);
registerConfirmPassword = findViewById(R.id.register_confirm_password);
registerRegisterButton = findViewById(R.id.register_register_button);
registerLoginButton = findViewById(R.id.register_login_button);
registerProgressBar = findViewById(R.id.register_progressBar);
firebaseFirestore = FirebaseFirestore.getInstance();
user_id = registerUsername.getText().toString();
registerLoginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent loginIntent = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(loginIntent);
}
});
registerRegisterButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String username = registerUsername.getText().toString();
String email = registerEmail.getText().toString();
String password = registerPassword.getText().toString();
String confirmPassword = registerConfirmPassword.getText().toString();
if (!TextUtils.isEmpty(username) && !TextUtils.isEmpty(email) && !TextUtils.isEmpty(password) && !TextUtils.isEmpty(confirmPassword)) {
if (password.equals(confirmPassword)) {
registerProgressBar.setVisibility(View.VISIBLE);
Map<String, String> usersMap = new HashMap<>();
usersMap.put("username", username);
usersMap.put("email", email);
usersMap.put("password", password);
firebaseFirestore.collection("Users").document(user_id).set(usersMap).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toasty.success(RegisterActivity.this, "Successfully Registered", Toast.LENGTH_SHORT).show();
Intent loginIntent = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(loginIntent);
registerProgressBar.setVisibility(View.INVISIBLE);
}
});
} else {
Toasty.error(RegisterActivity.this, "Passwords Don't Match", Toast.LENGTH_SHORT).show();
}
}
}
});
}}
I want the "user_id" to be the document id and NOT another id generated by Firestore.
Can someone please help? And Thanks in advance.
You're setting user_id at the beginning of your onCreate, probably when the EditText registerUsername doesn't contain any text. This means user_id will always be empty, no matter what happens in this activity.
You can't pass an empty string to document(). You need an actual string value there that's also a valid Firestore document ID. Try getting the string value in registerUsername after they've filled out the form, not before.