I just want to update the count table one time but it keeps updating in the infinite loop can someone help me with this.
referral_code=referral_editText.getText().toString();
db.collection(REFERRAL_CODE_KEY).addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot queryDocumentSnapshots, #Nullable FirebaseFirestoreException e) {
assert queryDocumentSnapshots != null;
for(DocumentSnapshot documentSnapshots:queryDocumentSnapshots){
if(referral_code.equals(documentSnapshots.get(REFERRAL_CODE).toString()))
{
count = parseInt(String.valueOf(documentSnapshots.get(REFERRAL_COUNT)))+1;
Map<String, Object> referralCountDocData = new HashMap<>();
referralCountDocData.put(REFERRAL_COUNT,count);
klog.d("### referral",count+"");
db.collection(REFERRAL_CODE_KEY)
.document(documentSnapshots.getId())
.update(referralCountDocData).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
finish();
}
});
}
}
}
});
Maybe, you could do something like this not everythng is perfect but it gives you a nice idea.
oldCount-> you can read it from document.getData()
var docRef = db.collection(REFERRAL_CODE_KEY).doc(referral_code);
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
Log.d(TAG, "DocumentSnapshot data: " + document.getData());
//read oldCount here from document.getData()
Map<String, Object> docData= new HashMap<>();
docData.put(REFERRAL_COUNT, oldcount + 1);
docRef.set(docData)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully written!");
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error writing document", e);
}
});
} else {
Log.d(TAG, "No such document");
}
} else {
Log.d(TAG, "get failed with ", task.getException());
}
}
});
You can detach your listener, so that callback stop getting called.
As per official document https://firebase.google.com/docs/firestore/query-data/listen#detach_a_listener You need to use remove method to detach listener
Query query = db.collection("cities");
ListenerRegistration registration = query.addSnapshotListener(
new EventListener<QuerySnapshot>() {
// ...
});
// ...
// Stop listening to changes
registration.remove();
Related
I am stuck with a small issue. I have data in firestore document which should be loaded in autocomplete text view. However, my firestore callback is returning data after my autocomplete code execute. My question is how to load data after callback completes returning document data successfully.
Following is my code...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_search_instructor);
activitySearchInstructorBinding=ActivitySearchInstructorBinding.inflate(getLayoutInflater());
View view=activitySearchInstructorBinding.getRoot();
setContentView(view);
fillInstructorList();
Log.d(TAG, "onCreate: instructorList into ACTV...");
AutoCompleteInstructorAdapter autoCompleteInstructorAdapter = new AutoCompleteInstructorAdapter(this,instructorList);
activitySearchInstructorBinding.searchInstructorInstructorIdACTV.setAdapter(autoCompleteInstructorAdapter);
activitySearchInstructorBinding.searchInstructorInstructorIdACTV.setOnItemClickListener(this);
}
public void fillInstructorList(){
Log.d(TAG, "fillInstructorList: Inside function...");
instructorList = new ArrayList<>();
instructorList.add(new Instructor("HI821010A01","Himani Kumar","40","5",
"$50","20","10","M"));
documentReference=firebaseFirestoreDB.document(instructorsCollectionRoot+"/"+"NSW");
documentReference.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if(task.isSuccessful()){
DocumentSnapshot documentSnapshot = (DocumentSnapshot) task.getResult();
if(documentSnapshot.exists()){
Log.d(TAG, "fillInstructorList: document exists...");
Map<String, Object> dataMap = documentSnapshot.getData();
Log.d(TAG, "onSuccess: hMap size: " + dataMap.size());
for(Map.Entry m : dataMap.entrySet()){
Log.d(TAG, "onSuccess: m.getKey(): " + m.getKey());
HashMap<String,String> innerMap = (HashMap<String, String>) m.getValue();
Log.d(TAG, "onSuccess: hMap size: " + innerMap.size());
String instructorID=null,instructorName=null,instructorAge=null,instructorRating=null,
instructorRate=null,drivingSince=null,instructorSince=null,instructorGender=null;
for(Map.Entry innerm : innerMap.entrySet()) {
if(innerm.getKey().equals("instructorID")) instructorID=innerm.getValue().toString();
if(innerm.getKey().equals("instructorName")) instructorName=innerm.getValue().toString();
}
instructorList.add(new Instructor(instructorID,instructorName,instructorAge,instructorRating,
instructorRate,drivingSince,instructorSince,instructorGender));
Log.d(TAG, "onSuccess: instructorList.size: " + instructorList.size());
}
}
else
Log.d(TAG, "fillInstructorList: document doesn't exists :P");
}else
Log.d(TAG, "fillInstructorList: task is not successful");
}
});
}
You should try to fill your Adapter once the data loads, since reading in firebase is an asynchronous process. Here an example:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_search_instructor);
// ...
fillInstructorList();
}
public void fillInstructorList() {
// ...
documentReference.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
// Validation and data fill process
AutoCompleteInstructorAdapter autoCompleteInstructorAdapter = new AutoCompleteInstructorAdapter(this,instructorList);
activitySearchInstructorBinding.searchInstructorInstructorIdACTV.setAdapter(autoCompleteInstructorAdapter);
activitySearchInstructorBinding.searchInstructorInstructorIdACTV.setOnItemClickListener(this);
}
});
}
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
When send user data to firestore and login again the system not read this code , he join already to (if) after add data but return failed because I think firestore accept write only is there any solution?
if (snapshot.exists()) {
return snapshot.getString("ID");
}
Code
FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance();
DocumentReference documentReference = firebaseFirestore.collection("Players").document(saveSystem.LoadStringData("LoginType").equals("Facebook") ? "F" + saveSystem.LoadStringData("ID") : "G" + saveSystem.LoadStringData("ID"));
firebaseFirestore.runTransaction(new Transaction.Function<Object>() {
#Override
public Object apply(Transaction transaction) throws FirebaseFirestoreException {
DocumentSnapshot snapshot = transaction.get(documentReference);
if (snapshot.exists()) {
return snapshot.getString("ID");
} else {
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("ID", saveSystem.LoadStringData("ID"));
return hashMap;
}
}
}).addOnSuccessListener(new OnSuccessListener<Object>() {
#Override
public void onSuccess(Object aObject) {
Toast.makeText(Test.this, "" + aObject, Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
Sorry for simple English language.
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'm making a signup activity for an app and something weird is happening can you help me?
this is the code for signup some on and it works if I comment the signOut function but I need it to signout after saving the data in the FirebaseAuth and the Firestore.
I don't get even the logs.
public void registUser() {
mAuth = FirebaseAuth.getInstance();
mAuth.createUserWithEmailAndPassword(user.getEmail(), user.getPassword()).addOnCompleteListener(SignUpUserActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Toast.makeText(SignUpUserActivity.this, "Sucesso", Toast.LENGTH_SHORT).show();
// Sign in success, update UI with the signed-in user's information
//FirebaseUser user = mAuth.getCurrentUser();
user.setId(task.getResult().getUser().getUid());
user.save();
mAuth.signOut();
finish();
} else {
String erro = "";
try {
throw task.getException();
} catch (FirebaseAuthWeakPasswordException e) {
erro = "Digite uma senha mais forte";
} catch (FirebaseAuthInvalidCredentialsException e) {
erro = "Email invalido";
} catch (FirebaseAuthUserCollisionException e) {
erro = "Email Registado";
} catch (Exception e) {
erro = "Erro generico";
e.printStackTrace();
}
Toast.makeText(SignUpUserActivity.this, erro, Toast.LENGTH_SHORT).show();
}
}
});
}
I think its because it takes to long to save things in the database.
I have no problems with the Auth part.
Thank you.
this is the save function.
public void save(){
DocumentReference reference = FirebaseFirestore.getInstance().document("/Clinicas/" + clinic + "/Profissionais/" + id + "/");
Map<String, Object> dataToSave = new HashMap<String, Object>();
dataToSave.put("Name", name);
dataToSave.put("email", email);
dataToSave.put("clinic", clinic);
dataToSave.put("Job", job);
reference.set(dataToSave).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d("artur", "Saved");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w("artur", "Not Saved",e);
}
});
}
To sovle this, please use the following code:
user.setId(task.getResult().getUser().getUid());
userRef.set(user).addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
mAuth.signOut();
}
});
When you sign-out, you need to be sure that your write operation is done and this can only be achieved using addOnSuccessListener.
public void save(){
DocumentReference reference = FirebaseFirestore.getInstance().document("/Clinicas/" + clinic + "/Profissionais/" + id + "/");
Map<String, Object> dataToSave = new HashMap<String, Object>();
dataToSave.put("Name", name);
dataToSave.put("email", email);
dataToSave.put("clinic", clinic);
dataToSave.put("Job", job);
reference.set(dataToSave).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d("artur", "Saved");
mAuth = FirebaseAuth.getInstance();
mAuth.signOut();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w("artur", "Not Saved",e);
}
});
}