I would like to cover all cases of failure in firebase/firestore. I've seen functions trigger OnFailure callback, but under what circumstances does OnCanceled get triggered? I haven't been able to force any triggers of OnCanceled() for a variety of functions such as writes/deletes as well as operations on FirebaseUser and AuthUI and haven't seen any documentation. Are these cases documented somewhere?
FirebaseDatabase.getInstance().getReference("users/test").setValue("blabla")
.addOnSuccessListener(new OnSuccessListener<Void>()
{
#Override
public void onSuccess(Void aVoid)
{
Log.v("TEST", "DB WRITE SUCCESS");
}
})
.addOnFailureListener(new OnFailureListener()
{
#Override
public void onFailure(#NonNull Exception e)
{
Log.v("TEST", "DB WRITE FAILURE " + e);
}
})
.addOnCanceledListener(new OnCanceledListener()
{
#Override
public void onCanceled()
{
Log.v("TEST", "DB WRITE CANCELLED");
}
});
FirebaseFirestore fs = FirebaseFirestore.getInstance();
fs.collection("users").document("blabla").set(data)
.addOnSuccessListener(new OnSuccessListener<Void>()
{
#Override
public void onSuccess(Void aVoid)
{
Log.v("TEST", "FS WRITE SUCCESS");
}
})
.addOnFailureListener(new OnFailureListener()
{
#Override
public void onFailure(#NonNull Exception e)
{
Log.v("TEST", "FS WRITE FAILURE " + e);
}
})
.addOnCanceledListener(new OnCanceledListener()
{
#Override
public void onCanceled()
{
Log.v("TEST", "FS WRITE CANCELLED");
}
});
FirebaseUser user = mAuth.getCurrentUser();
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(name)
.build();
user.updateProfile(profileUpdates)
.addOnSuccessListener(new OnSuccessListener<Void>()
{
#Override
public void onSuccess(Void aVoid)
{
Log.v("NICK", "SUCCESS UPDATED PROFILE");
}
})
.addOnCanceledListener(new OnCanceledListener()
{
#Override
public void onCanceled()
{
Log.w("NICK", "CANCELED UPDATE PROFILE");
}
})
.addOnFailureListener(new OnFailureListener()
{
#Override
public void onFailure(#NonNull Exception e)
{
Log.w("NICK", "FAILED TO UPDATE PROFILE");
}
});
AuthUI.getInstance().delete(this)
.addOnSuccessListener(new OnSuccessListener<Void>()
{
#Override
public void onSuccess(Void aVoid)
{
Log.v("AUTHUI", "SUCCESS DELETED ACCNT");
}
})
.addOnCanceledListener(new OnCanceledListener()
{
#Override
public void onCanceled()
{
Log.w("AUTHUI", "CANCELED DELETE ACCNT");
}
})
.addOnFailureListener(new OnFailureListener()
{
#Override
public void onFailure(#NonNull Exception e)
{
Log.w("AUTHUI", "FAILED TO DELETE ACCNT " + e);
}
});
under what circumstances does OnCanceled get triggered?
It doesn't. Task cancelation only happens for tasks that are specifically designed to be cancelable. That doesn't happen to Firestore tasks.
Related
I want to get and delete all the documents in a subcollection called "journal" but it doesn't work and did not show any toast message or errors.
It would be very helpful if someone tells me what is wrong. Thank you a lot.
This is the code I use to get and delete all the documents in a subcollection:
final String userid = FirebaseAuth.getInstance.getCurrentUser().getUid();
FirebaseFirestore. getInstance().collection("main").document(userid).collection("journal").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (final QueryDocumentSnapshot document : task.getResult()) {
db.collection("main").document(userid).collection("journal").document(document.getId()).delete().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(SettingsActivity.this, "Deleted: " + document.getId(), Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(SettingsActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(SettingsActivity.this, "error getting: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
Firestore structure :
collection(main) ---> document(userid)---> collection(journal)---> document 1
---> document 2
--> document 3
Try this.
final String userid = FirebaseAuth.getInstance().getCurrentUser().getUid();
FirebaseFirestore.getInstance().collection("main").document(userid).collection("journal").get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
for (DocumentSnapshot document: queryDocumentSnapshots.getDocuments()) {
db.collection("main").document(userid).collection("journal").document(document.getId()).delete().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(SettingsActivity.this, "Deleted: " + document.getId(), Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(SettingsActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
}
});
Also, please make sure you have set your db rules to allow delete event
I'm doing a project called e-school. It has 4 types of users which uses Firebase authentication and Firebase realtime database to login to their accounts, Anyway, I'm getting issues while working with Firebase realtime database and Firebase authentication. I'm letting users to their respective dashboards comparing the authentication data with the realtime database.
//Registration Code
auth.createUserWithEmailAndPassword(email.getText().toString(), password.getText().toString())
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
Users user = new Users();
user.setE_mail(email.getText().toString());
user.setNumber(Phone.getText().toString());
user.setPassword(password.getText().toString());
user.setU_name(username.getText().toString());
users.child("principal").child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(user)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Snackbar.make(rootLayout, "Registration Success",Snackbar.LENGTH_LONG)
.show();
return;
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Snackbar.make(rootLayout, "Registration Failed: "+e.getMessage(), Snackbar.LENGTH_LONG)
.show();
return;
}
});
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Snackbar.make(rootLayout, "Failed :"+e.getMessage(),Snackbar.LENGTH_LONG)
.show();
return;
}
});
}
});
//Login COde
auth.signInWithEmailAndPassword(t_email.getText().toString(), t_password.getText().toString())
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
id = auth.getUid();
teacherValidation(id);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Snackbar.make(rootLayout,"Authentication Failed", Snackbar.LENGTH_SHORT).show();
}
});
//TeacherValidate
private void teacherValidation(final String id) {
users = db.getInstance().getReference("Users/teachers");
users.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.getKey().equals(id)){
Toast.makeText(MainActivity.this," "+id,Toast.LENGTH_SHORT).show();
Intent it = new Intent(MainActivity.this, teachers.class);
it.putExtra("UID", id);
startActivity(it);
finish();
}else{
Toast.makeText(MainActivity.this, "No Teacher Esxist With the Given Credientialss", Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
It is not necessary to get all teachers details on client side. Instead you can directly check in database for that user, it'll increase the performance of app also.
Just modify teacherValidation method like this.
private void teacherValidation(final String id) {
users = db.getInstance().getReference("Users/teachers").child(id);
users. addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
// If below condition checks true,
// that means user exists on teacher node, so probably he/she is a teacher.
if(dataSnapshot.getValue() != null){
Toast.makeText(MainActivity.this," "+id,Toast.LENGTH_SHORT).show();
Intent it = new Intent(MainActivity.this, teachers.class);
it.putExtra("UID", id);
startActivity(it);
finish();
}else{
Toast.makeText(MainActivity.this, "No Teacher Exist With the Given Credientialss", Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
I got this code snippet. Probably addListenerForSingleValueEvent is your method.
Pay special attention in the way the query is built, calling a first child which is the table called "users" and then a second child which is a user with a specific userId. FUser is equivalent to your Users class.
Try it...
private void getFirebaseUserInfo(final String userId, final GetUserInfoListener userInfoListener) {
DatabaseReference userIdReference = getDatabaseReference().child("users").child(userId);
userIdReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
try {
final Users user = dataSnapshot.getValue(FUser.class);
if (!user.email.isEmpty()) {
// Do whatever
} else {
userInfoListener.onSuccess(user);
}
} catch(DatabaseException e) {
userInfoListener.onFailure(new Exception(e.getMessage()));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
userInfoListener.onFailure(new Exception(databaseError.getMessage()));
}
});
}
Also, look at the difference:
Difference between addValueEventListener() and addListenerForSingleValueEvent() of firebase
I am trying to replace an image in Firebase storage with a new one by first deleting the old and then adding the new. The problem is the deletion. I cannot seem to get it to work. Here is the relevant code:
private void uploadFile(){
progressBar.setVisibility(View.VISIBLE);
db2 = FirebaseFirestore.getInstance().collection("Users").document(id);
storageReference.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
StorageReference fileReference = storageReference.child(System.currentTimeMillis()
+ "."+ getFileExtension(imageuri));
mUploadTask = fileReference.putFile(imageuri).
addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(final UploadTask.TaskSnapshot taskSnapshot) {
Task<Uri> urlTask = taskSnapshot.getStorage().getDownloadUrl();
while (!urlTask.isSuccessful());
Uri downloadUrl = urlTask.getResult();
db2.update("Image URI",downloadUrl.toString()).addOnSuccessListener(
new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(settings_activity
.this, "DP change added." ,
Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
}
}
).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(settings_activity.this, "FIRESTROE ERROR "+e.getMessage(), Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
}
});
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(settings_activity.this, "FILE STRORAGE "+e.getMessage(), Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
}
});
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(settings_activity.this, "DELETION ERROR: "+e.getMessage(), Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
}
});
}
This is the storage reference I used in the code above:
FirebaseStorage.getInstance().getReference().child("profile_pics/"+FirebaseAuth.getInstance().getCurrentUser().getUid());
I have following method which i call, but i dont see any call back getting called.
Log.d(TAG,"adding to firebase");
// Create a new user with a first and last name
Map<String, Object> user = new HashMap<>();
user.put("first", "rambo");
user.put("last", "Lovelace");
user.put("born", 1815);
db.collection("aks")
.add(user)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
Log.d(FIRE_TAG, "akshay:DocumentSnapshot added with ID: " + documentReference.getId());
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(FIRE_TAG, "akshay:Error adding document", e);
}
})
.addOnCanceledListener(new OnCanceledListener() {
#Override
public void onCanceled() {
Log.w(FIRE_TAG,"akshayoncancel listner");
}
})
.addOnCompleteListener(new OnCompleteListener<DocumentReference>() {
#Override
public void onComplete(#NonNull Task<DocumentReference> task) {
Log.w(FIRE_TAG,"on completed listner");
}
});
Log.d(TAG,"done");
I see that "adding to firebase" and "done" printed on console, but nothing success/failure callbacks are not getting called. Why so?
I am trying to delete a file from Firebase Storage using the files URL.
My issue is that the getReferenceFromUrl() can not be resolved.
Sample code here:
StorageReference mStorageRef;
String storageurl = "http:sample"
mStorageRef = FirebaseStorage.getInstance().getReference();
StorageReference ref2 = mStorageRef.getReferenceFromUrl(storageurl);
ref2.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
// File deleted successfully
Toast.makeText(getContext(), "file deleted", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onSuccess: deleted file");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Uh-oh, an error occurred!
Log.d(TAG, "onFailure: did not delete file");
}
});
StorageReference storageReference = FirebaseStorage.getInstance().getReferenceFromUrl("https://firebasestorage.googleapis.com/v0/b/***********************-5fac-45b6-bbda-ed4e8a3a62ab");
storageReference.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
// File deleted successfully
Log.e("firebasestorage", "onSuccess: deleted file");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Uh-oh, an error occurred!
Log.e("firebasestorage", "onFailure: did not delete file");
}
});
Snippet for Delete file from Firebase Storage Using URL:
StorageReference storageReference = FirebaseStorage.getInstance().getReferenceFromUrl("https://firebasestorage.googleapis.com/v0/b/***********************-5fac-45b6-bbda-ed4e8a3a62ab");
storageReference.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
// File deleted
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Error
}
});
try this I have tried this and its working
String storageUrl = "Chat-Images/1498804025000.png";
StorageReference storageReference = FirebaseStorage.getInstance().getReference().child(storageUrl);
storageReference.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
// File deleted successfully
Log.d(TAG, "onSuccess: deleted file");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Uh-oh, an error occurred!
Log.d(TAG, "onFailure: did not delete file");
}
});
In case you are using kotlin, this is the code:
val storageReference: StorageReference = FirebaseStorage.getInstance().getReferenceFromUrl(urifinal) //urifinal is a String variable with the url
storageReference.delete().addOnSuccessListener {
//File deleted
Log.d("storage", "Done")
}.addOnFailureListener {
//failed to delete
Log.d("storage", "error while deleting")
}
I think what you need is getStorage() to be able to use getReferenceFromUrl(),
eg:
FirebaseStorage.getInstance().getStorage().getReferenceFromUrl(fileURL);