Android Java FirebaseFirestore Write Error - java

i am trying to add my auth users in my Cloud Firestore. Here is my code below,
FirebaseFirestore db;
db = FirebaseFirestore.getInstance();
User newUser = new User(nameRegister, surnameRegister, usernameRegister, emailRegister);
db.collection("users")
.add(newUser)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
Log.d("TAG", "DocumentSnapshot added with ID: " + documentReference.getId());
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w("TAG", "Error adding document", e);
}
});
I read official Firebase document and did how they suggest.
I can not write my data to db.
Where am I doing wrong? I am waiting for your help and thank you very much in advance.

Related

How to resolve this onSuccesListener error?

So in the following on Success Listener code:
database.collection("users")
.add(users)
.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
}
})
I am getting the error:
'addOnSuccessListener(com.google.android.gms.tasks.OnSuccessListener<? super com.google.firebase.firestore.DocumentReference>)' in 'com.google.android.gms.tasks.Task' cannot be applied to '(anonymous com.google.android.gms.tasks.OnSuccessListener<com.google.firebase.firestore.DocumentSnapshot>)'
How to resolve this?
Assuming that you have a database structure that looks like this:
Firestore-root
|
--- users (collection)
|
--- $uid (document)
|
--- // user fields.
To check if a particular users already exists, please use the following lines of cde:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
FirebaseFirestore db = FirebaseFirestore.getInstance();
DocumentReference uidRef = db.collection("users").document(uid);
uidRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document != null) {
Log.d("TAG", "User already exists.");
} else {
Log.d("TAG", "User doesn't exist.");
}
} else {
Log.d("TAG", task.getException().getMessage()); //Never ignore potential errors!
}
}
});
It's as the stacktrace implies, you're using the wrong parameter in the listener. You need to use OnSuccessListener<DocumentReference> or any superclass of DocumentReference.
EDIT:
Reference from Firebase : Add a document
You need to use DocumentReference:
Map<String, Object> data = new HashMap<>();
data.put("name", "Tokyo");
data.put("country", "Japan");
db.collection("cities")
.add(data)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
Log.d(TAG, "DocumentSnapshot written with ID: " + documentReference.getId());
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error adding document", e);
}
});
Use the resulting id to get the document again.

When uploading a image for one user to firebase storage, the link of the image updates for every user in database

I'm creating this app in Android Studio using Firebase Realtime Database and Firebase Storage. When a user registers through my app the data will store in the Firebase Realtime Database. Then on the profile page, there is a place to upload a picture. When a user uploads a picture it will store in the firebase storage and the link will update in the database on a new field under the respective user.
It worked correctly the last time I checked. But when I added a new user and uploaded his profile picture, that link updates on every other user as well. But in the Firebase Storage, there were no changes. It only happens in Firebase Realtime Database. I couldn't find any solution to this.
This is the part I update the link of the profile.
private void UploadProfPic(Uri image_uri) {
final StorageReference strRef = storageReference.child("users/"+ email_i +"/profile.jpg");
strRef.putFile(image_uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(getApplicationContext(), "Image has been uploaded", Toast.LENGTH_LONG).show();
strRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Picasso.get().load(uri).fit().into(profPic);
imgRef = uri.toString();
usrRF.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot dss : snapshot.getChildren()){
String key = dss.getKey();
Map<String, Object> updates = new HashMap<String, Object>();
updates.put("profile_url", imgRef);
usrRF.child(key).updateChildren(updates);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(getApplicationContext(), "Error", Toast.LENGTH_LONG).show();
}
});
}
});
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull /*#org.jetbrains.annotations.NotNull*/ Exception e) {
Toast.makeText(getApplicationContext(), "Failed to update profile picture", Toast.LENGTH_LONG).show();
}
});
}
here usrRf = FirebaseDatabase.getInstance().getReference("users");
Here is my database structure
Any help will be appreciated. Thank you.
According to your last comment:
Yes, Firebase email Authentication
Then you should consider saving user data, under the UID that comes from the authentication process and not under a pushed ID, as I see in your screenshot now. This means that you should add a User object to the database using:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("users");
usersRef.child(uid).setValue(userObj).addOnCompleteListener(/* ... /*);
And not using:
usersRef.push().setValue(userObj).addOnCompleteListener(/* ... /*);
That beeing said, to be able to update the image that is uploaded to the node of the logged-in user, then please use the following updated method:
final StorageReference strRef = storageReference.child("users/"+ email_i +"/profile.jpg");
strRef.putFile(image_uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(getApplicationContext(), "Image has been uploaded", Toast.LENGTH_LONG).show();
strRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Picasso.get().load(uri).fit().into(profPic);
imgRef = uri.toString();
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("users");
Map<String, Object> updates = new HashMap<String, Object>();
updates.put("profile_url", imgRef);
usersRef.child(uid).updateChildren(updates).addOnSuccessListener(/* ... /*);
}
});
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull /*#org.jetbrains.annotations.NotNull*/ Exception e) {
Toast.makeText(getApplicationContext(), "Failed to update profile picture", Toast.LENGTH_LONG).show();
}
});
See, there is no for-loop involed? That was causing you trouble, as it was updating all child under "users" node.

How to check Firebase data success write data in database (handle error)?

How to check Firebase data success write data in database (handle error)?
because I want to set massage Toast if data write success show massage
reg_money.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mAuth = FirebaseAuth.getInstance();
FirebaseUser userfirebase = mAuth.getInstance().getCurrentUser();
mDatabase = FirebaseDatabase.getInstance();
mDbRef = mDatabase.getReference("Student/information");
String email = userfirebase.getEmail();
Uaser_register_money user = new Uaser_register_money(namesemster, email.substring(0,11), count2);
mDbRef.child("Student/information").setValue(user);
}
});
Just Add Listeners
mDbRef.child("Student/information").setValue(user)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
// Write was successful!
// ...
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
// Write failed
// ...
}
});

android firestore: retrieve custom object from HashMap

I would like to store userdata in a document in Firestore. To do that I’m using a HashMap:
String userID = mAuth.getCurrentUser().getUid();
User user = new User(stringMail, stringUsername, stringGender, stringBirthday,
stringCountry, registeredOn);
HashMap<String, User> userHashMap = new HashMap<>();
userHashMap.put("userdata", user);
users.document(userID).set(userHashMap, SetOptions.merge())
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(RegisterActivity.this, "Upload completed to Firestore!", Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(RegisterActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(RegisterActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
});
That works pretty good. I do have a problem though with retrieving the data. As the data is stored in a HashMap I can’t use following code:
String userID = mAuth.getUid();
users.document(userID).get()
.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
Map<String, Object> userHashMap = new HashMap<String, Object>();
userHashMap = documentSnapshot.getData();
User user = (User) userHashMap.get("userdata");
I also can't use:
User user = documentSnapshot.toObject(User.class);
So I wondered whether someone can suggest a way how to retrieve a custom object from a HashMap? I should also mention that the document will contain a second HashMap.

Get and update Data from Firestore - Problems

For my app, I have a lot of occasions, where I need to retrieve and write data to Firestore.
I am able to write new data and to get and display data. I can also overwrite data in one class, but having troubles right now in another one despite using the same method.
FirebaseFirestore db = FirebaseFirestore.getInstance();
FirebaseUser currUser = FirebaseAuth.getInstance().getCurrentUser();
DocumentReference userDocRef = db.collection("Users").document(currUser.getEmail());
//access current values saved under this user
userDocRef.get().addOnSuccessListener(new
OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
User currentUser = documentSnapshot.toObject(User.class);
warmups_skipped = currentUser.getWarmupsSkipped()+1;
Log.d(TAG, "DocumentSnapshot successfully retrieved! " + warmups_skipped);
}
});
I can see in logCat that the local variable is being changed. All good so far.
Then I call this method immediately after:
FirebaseFirestore db = FirebaseFirestore.getInstance();
FirebaseUser currUser = FirebaseAuth.getInstance().getCurrentUser();
DocumentReference userDocRef = db.collection("Users").document(currUser.getEmail());
Map<String, Object> update = new HashMap<>();
update.put(WARMUPSSKIPPED, getWarmups_skipped());
userDocRef
.set(update, SetOptions.merge()).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "Document has been saved");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, "Document could not be saved");
}
});
}
Also here I get the TAG message displayed, but nothing gets changed in FireStore. I use the exact same second method in another class, where I do not check for, what is already online, but simply overwrite it.
Really appreciate the help!
Okay I figured it out eventually. Apparently I cannot have these two actions separate, so I put the second method inside the first one and now it seems to work. Not entirely sure why, though, cause the variables are class variables and should be accessible from both methods. If anyone else has that problem, here is how it works for me now:
FirebaseFirestore db = FirebaseFirestore.getInstance();
FirebaseUser currUser = FirebaseAuth.getInstance().getCurrentUser();
final DocumentReference userDocRef = db.collection("Users").document(currUser.getEmail());
//access current values saved under this user
userDocRef.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
User currentUser = documentSnapshot.toObject(User.class);
warmups_skipped = currentUser.getWarmupsSkipped()+1;
Map<String, Object> update = new HashMap<>();
update.put(WARMUPSSKIPPED, warmups_skipped);
userDocRef
.set(update, SetOptions.merge()).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "Document has been saved");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, "Document could not be saved" +e.toString());
}
});
Log.d(TAG, "DocumentSnapshot successfully retrieved! " + warmups_skipped);
}
});

Categories