Im trying to write on firebase realtime database via my android app using setValue() it works very well.. but i don't know how i can handle the error if something goes wrong
i tried try/catch and turning off the WIFI so the setValue function won't work
but it didn't seem to catch any exception
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("message");
try{
myRef.setValue("Hello, World!");
}catch(Exception e){
e.printStackTrace();
}
There are many methods you can use to handle this. You can set any of several listeners to monitor the result state of a setValue() call:
onCompleteListener()
onFailureListener()
onSuccessListener()
My personal preference is the onCompleteListener() because it allows me to simultaneously check for success and failure with minimal lines of code. Here's an implementation:
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("message");
myRef.setValue("Hello, World!").addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()) {
// handle success event
}
else {
// handle failure event
// You can get the exact exception using task.getException()
}
}
});
I hope this helps. Merry coding!
You can use Completion Callback.
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("message");
myRef.setValue("Hello, World!")
.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
// ...
}
});
Related
I'm using Firebase for login, but I want the user to also be added to the Real-Time Database so I can link the User with further data.
When a user registers, I can see that the user has been added to the authentication section of Firebase, and the user is able to log in but it does not get added to the Real-Time Database.
Here is my code
db = FirebaseDatabase.getInstance();
users = db.getReference("Users");
User user = new User();
user.setEmail((editEmail.getText().toString()));
user.setPassword((editPass.getText().toString()));
user.setName((editName.getText().toString()));
user.setPhone(editPhone.getText().toString());
users.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(user)
I also set an onSuccess/fail listener with Toasts letting me know if it failed or not. And neither of the toasts execute. I do have read/write enabled on my DB.
Define Variable.
private DatabaseReference userRef;
in OnCreate method.
userRef = FirebaseDatabase.getInstance().getReference().child("Users");
in a signup button
String getUserName = usernameEditText.getText.toString;
String getBio = bioEditText.getText.toString;
//and you should use the validates
if(getUserName.equals("")
{
usernameEditText.setError("Field Required");
}
else if(getBio.equals("")
{
bioEditText.setError("Field Required");
}
else
{
final HashMap<String , Object> profileMap = new HashMap<>();
profileMap.put("uid" , FirebaseAuth.getInstance().getCurrentUser().getUid());
profileMap.put("name" , getUserName);
profileMap.put("status" , getBio);
userRef.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.updateChildren(profileMap)
.addOnCompleteListener(new OnCompleteListener<Void>()
{
#Override
public void onComplete(#NonNull Task<Void> task)
{
if (task.isSuccessful())
{
Log.v("Profile Updated" , "Profile Updated Successfully");
Intent intent = new Intent(SettingsActivity.this , MainActivity.class);
startActivity(intent);
finish();
progressDialog.dismiss();
Toast.makeText(SettingsActivity.this, "Your profile Info has been updated", Toast.LENGTH_SHORT).show();
}
}
});
}
I was wondering if there was a way to edit the name and email via code in Android Studio, to change it in Cloud Firestore. I made a program where it only changes the name in real-time and when logged off, and logged in again it changes back to the previous one which is in Cloud Firestore.
vardas is an EditText field in the app design.
My code:
public void updateProfile(final View view) {
view.setEnabled(false);
vardas1 = vardas.getText().toString();
FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
UserProfileChangeRequest request = new UserProfileChangeRequest.Builder()
.setDisplayName(vardas1)
.build();
firebaseUser.updateProfile(request)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
view.setEnabled(true);
Toast.makeText(Profile.this, "SÄ—kmingai atnaujintas profilis", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
view.setEnabled(true);
Log.e(TAG, "onFailure: ", e.getCause());
}
});
}
I was wondering if there was a way to edit the name and email via code in Android Studio, to change it in Cloud Firestore.
Yes, there is. According to the official documentation regarding how to update a document in Cloud Firestore:
To update some fields of a document without overwriting the entire document, use the update() method.
Assuming you want to update the name and email of the authenticated user that exists at the following reference:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference usersRef = rootRef.collection("users");
DocumentReference uidRef = usersRef.document(uid);
Try the following lines of code:
uidRef.update(
"name", "John",
"email", "john#email.com"
).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully updated!");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error updating document", e);
}
});
The result of using this is code, is the update of the name property with "John".
What you are doing in your code is nothing else than updating the name in the FirebaseUser object. That operation is not related in any way with Firestore. So updating the FirebaseUser it doesn't mean that the user will be also updated in the Firestore database. There are two different separate operations that are not related.
Here mAuth.createUserWithEmailAndPassword this method is working but the database method not working.
i make the values true in realtime database .
mAuth.createUserWithEmailAndPassword(email,password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
user u = new user(username,email);
>the below method is not working
database.child(Objects.requireNonNull(mAuth.getCurrentUser()).getUid())
.setValue(u).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
Toast.makeText(signUp.this,"done",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(signUp.this,"failed",Toast.LENGTH_SHORT).show();
}
}
});
}else{
Toast.makeText(signUp.this,"loginfailed",Toast.LENGTH_SHORT).show();
}
}
});
Things to check:
1) Did you initialize your database reference:
DatabaseReference database = FirebaseDatabase.getInstance().getReference();
2) Did you initialize your auth:
FirebaseAuth mAuth = FirebaseAuth.getInstance();
3) Are your security rules for real time database allowing read and write?
4) Are your email and password that are being passed to the function null?
problem solved. The problem is only occurring in the emulator . In the physical device, it works fine
I am making a firebase notes app for android as a project (I'm a beginner and never done anything like this). My problem at the moment is that every note made, no matter what user made it, is available for every user to see. I want to make it that every user can only read/write their own notes but all the rules I found and tried so far made it that no notes are sent to the database at all or are not shown. I tried playing around with the code itself as well, but everything I did made the app crash but I'm open to suggestions.
The problem (logged in as user 2) :
The database with two users and the two notes:
I've tried solutions from other similar posts like this:
"rules": {
"tasks": {
"$userId": {
".read": "auth.uid == $userId",
".write": "auth.uid == $userId",
}
}
}
}
But none worked properly so far.
User creation:
fAuth.createUserWithEmailAndPassword(email,password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
fUserDatabase.child(fAuth.getCurrentUser().getUid()).child("basic").child("name")
.setValue(name).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
progressDialog.dismiss();
Intent mainIntent = new Intent(RegisterActivity.this, MainActivity.class);
startActivity(mainIntent);
finish();
Toast.makeText(RegisterActivity.this, "User Created", Toast.LENGTH_SHORT);
} else {
progressDialog.dismiss();
Toast.makeText(RegisterActivity.this, "Error: " + task.getException().getMessage(), Toast.LENGTH_SHORT);
}
}
});
} else {
progressDialog.dismiss();
Toast.makeText(RegisterActivity.this, "Error: " + task.getException().getMessage(), Toast.LENGTH_SHORT);
}
}
});
Note Creation:
(Not on the same page)
editText = findViewById(R.id.etx);
etd = findViewById(R.id.etdx);
button = findViewById(R.id.btnx);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference().child("posts").push();
Map<String, Object> map = new HashMap<>();
map.put("id", databaseReference.getKey());
map.put("title", editText.getText().toString());
map.put("desc", etd.getText().toString());
databaseReference.setValue(map);
Intent back = new Intent(NewNoteActivity.this, MainActivity.class);
startActivity(back);
}
});
I would like to make it so that every user can only see, edit and delete notes that they made themselves.
I found a solution that might be useful to anyone else who's having troubles with this kind of thing.
I changed the path in the note creation to this:
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference().child("Users").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("posts").push();
Then changed the part of the code that shows the notes accordingly.
This is how it was:
Query query = FirebaseDatabase.getInstance()
.getReference()
.child("posts");
This is how it is now:
Query query = FirebaseDatabase.getInstance()
.getReference()
.child("Users").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("posts");
You cannot keep data as relational database. because firebase database is flat heierarchy. when you design the database use always
/users/user-id/posts
+ item1
+ item2
this is the way you must implement. thanks.
I'm trying to create users table in Firebase realtime database.However, everytime user re-logins his previously entered data is being removed or overwritten.Couldnt understand how should I change it.
private void firebaseAuthWithGoogle(GoogleSignInAccount account) {
AuthCredential credential = GoogleAuthProvider.getCredential(account.getIdToken(), null);
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Toast.makeText(RegisterActivity.this,"Registration Is Succesfull",Toast.LENGTH_LONG).show();
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInWithCredential:success");
FirebaseUser user=mAuth.getCurrentUser();
final String databaseUserName=user.getDisplayName();
String name=mAuth.getCurrentUser().getDisplayName();
DatabaseReference myRootRef = FirebaseDatabase.getInstance().getReference().child("Users");
DatabaseReference userNameRef = myRootRef.child(databaseUserName);
//after that user is redirected to the main account activity.
Intent accountIntent = new Intent(RegisterActivity.this,UserAccountActivity.class);
accountIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(accountIntent);
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithCredential:failure", task.getException());
Toast.makeText(RegisterActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
// if signing up task is unsuccesfull we do make a error indication pretty much.
FirebaseAuthException e = (FirebaseAuthException )task.getException();
Toast.makeText(RegisterActivity.this, "Failed Registration: "+e.getMessage(), Toast.LENGTH_SHORT).show();
Log.e("LoginActivity", "Failed Registration", e);
}
}
});
}
So once I run the code, for the very first time it works perfectly fine and say I edit&add additional user info but once the user logs out and re-enters, everything is cleared out and node is again created.
Here you are saving the data in the database:
DatabaseReference myRootRef = FirebaseDatabase.getInstance().getReference().child("Users");
DatabaseReference userNameRef = myRootRef.child(databaseUserName);
Now on the second time, the data is not getting deleted or cleared, it cannot be deleted magically, the data is getting overridden. All you need to do is add a push() that will create a random id for each log in.
So like this:
DatabaseReference myRootRef = FirebaseDatabase.getInstance().getReference().child("Users").push();
DatabaseReference userNameRef = myRootRef.child(databaseUserName)
Edit:
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(Activity_name_here.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Toast.makeText(getApplicationContext(), "createUserWithEmail:onComplete:" + task.isSuccessful(), Toast.LENGTH_SHORT).show();
// If sign in fails, display a message to the user. If sign in succeeds
// the auth state listener will be notified and logic to handle the
// signed in user can be handled in the listener.
if (!task.isSuccessful()) {
Toast.makeText(getApplicationContext(), "Authentication failed." + task.getException(),
Toast.LENGTH_SHORT).show();
} else {
Here is the working version of the source code. You can use the very same code for facebook login as well. This code simply prevents user from overwriting when logging in again.
private void firebaseAuthWithGoogle(GoogleSignInAccount account) {
AuthCredential credential = GoogleAuthProvider.getCredential(account.getIdToken(), null);
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Toast.makeText(SignInActivity.this,"Registration Is Succesfull",Toast.LENGTH_LONG).show();
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInWithCredential:success");
//getting current users account
FirebaseUser user=mAuth.getCurrentUser();
//getting the display name of the current user to store them in our real time database
final String databaseUserName=user.getDisplayName();
//creating a child called users
final DatabaseReference myRootRef = FirebaseDatabase.getInstance().getReference().child("Users");
//here we make a control such that, if logged in user is exist in the realtime database
//if not exists, then we save them , if exists we continue with the else statement and break it.
myRootRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(!dataSnapshot.hasChild(databaseUserName)){
DatabaseReference userNameRef = myRootRef.child(databaseUserName);
//value is also set to user display name however it doenst have to be so
userNameRef.setValue(databaseUserName);
} else{
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
//after that user is redirected to the main account activity.
Intent accountIntent = new Intent(SignInActivity.this,UserAccountActivity.class);
accountIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(accountIntent);
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithCredential:failure", task.getException());
Toast.makeText(SignInActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
// if signing up task is unsuccesfull we do make a error indication pretty much.
FirebaseAuthException e = (FirebaseAuthException )task.getException();
Toast.makeText(SignInActivity.this, "Failed Registration: "+e.getMessage(), Toast.LENGTH_SHORT).show();
Log.e("LoginActivity", "Failed Registration", e);
}
}
});
}