I am trying to move firestore user records after authentication using batch. It seems to copy the records but not deleting.
Android app begins in anonymous mode, when user decides to signup, i try to move his records to the new SMS authenticated user.
Before signup, i get all user records using listRef.get() and a Success listener. I than save the resulted QuerySnapshot. After SMS authentication success, i use the snapshot to copy and delete.
I use the snapshot.getReference() to find the record. I confirmed in debug mode the reference path is correct
To make sure the delete code working, i made a test method and it worked.
The path in firestore is: lists/users/uid/
private void retrieveDataBeforeVerify() {
CollectionReference listRef = db.collection( "lists" ).document("users").
collection( mCurrentUser.getUid() );
listRef.get()
.addOnSuccessListener( new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
mQuerySnapshot = queryDocumentSnapshots; //Save snapshort
startPhoneNumberVerification(mPhoneNumberField.getText().toString()); //Start auth
}
} );
}
}
After the SMS authentications
private void moveDataToNewUser() {
if (mQuerySnapshot != null) {
if (mCurrentUser != null) {
DocumentReference listRef = db.collection( "lists" ).document( "users" );
WriteBatch batch = db.batch();
for (QueryDocumentSnapshot documentSnapshot : mQuerySnapshot) {
Main main = documentSnapshot.toObject( Main.class );
batch.set( listRef.collection( mCurrentUser.getUid() ).document( ) , main); //Copy working correctly
DocumentReference reference = documentSnapshot.getReference(); //On debug, reference shows correct path
batch.delete( reference ); //Delete does not work
}
batch.commit().addOnFailureListener( new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e( TAG, "moveDataToNewUser: batch failed" );
}
} ).addOnSuccessListener( new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d( TAG, "moveDataToNewUser: batch success" );
}
} );
}
}
}
update
I changed the reference to something non existing and still the onSuccess listener fires. How can it be??
DocumentReference reference = documentSnapshot.getReference().collection( "22" ).document("123");
update
if i comment the first two lines on the for-loop then delete is success. It looks as if the batch cannot process both set and delete on the same batch. I also tried using a transaction but got similar results. does this makes sense?
btw - i am using com.google.firebase:firebase-firestore:18.2.0, i believe it is the latest
for (QueryDocumentSnapshot documentSnapshot : mQuerySnapshot) {
//Main main = documentSnapshot.toObject( Main.class );
//batch.set( listRef.collection( mCurrentUser.getUid() ).document( ) , main); //Copy working correctly
DocumentReference reference = documentSnapshot.getReference(); //On debug, reference shows correct path
batch.delete( reference ); //Delete success!
}
Related
I wish to add fields in my firebase without overwriting it.
As you can see below, the user for my app will screen their emotions and the emotion will be uploaded to firebase.
Actually, user will be screened many times and each time they will get different emotions or same emotions.
Lets say the user screened their face and get Happiness, Sadness, Happiness respectively.
I wish to have my fields in the firebase console like this:
FaceEmotion: Happiness
FaceEmotion: Sadness
FaceEmotion: Happiness
Using my code below, at this moment I only get to overwrite the (FaceEmotion:) with same emotion values but not adding values as I wish like above. I've tried using array but I guess the problem is because the fieldname "FaceEmotion" is the same.
Is there a way for me to let Firestore generate autoID for the fieldname "FaceEmotion"? like maybe to have something like this:
FaceEmotion1: Happiness
FaceEmotion2: Sadness
FaceEmotion3: Happiness
String Emotion = EmotionType.toString();
userID = fAuth.getCurrentUser().getUid();
FaceEmotion = "FaceEmotion";
Map<String,Object> user = new HashMap<>();
user.put("FaceEmotion",Emotion);
DocumentReference documentReference = fStore.collection("users").document(userID).collection("FaceEmotion").document(FaceEmotion);
documentReference.update("FaceEmotion",FieldValue.arrayUnion(user)).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "onSuccess: Data has been saved "+ userID);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, "onFailure: " + e.toString());
}
});
The issue is on how you are writing to the document, the solution is to create a new document for every new emoton, this way you will be able to add emotions to that collection.
The code to write the emotions with this modification would be something like:
String emotion = EmotionType.toString();
userID = fAuth.getCurrentUser().getUid();
faceEmotion = "FaceEmotion";
Map<String,Object> val = new HashMap<>();
val.put("FaceEmotion",emotion);
DocumentReference documentReference = fStore.collection("users").document(userID).collection("FaceEmotion").document();
documentReference.set(val).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "onSuccess: Data has been saved "+ userID);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, "onFailure: " + e.toString());
}
});
I wanted to add new sub-Collection to a existing document. Should i create new POJO class to add Sub-Collection or any other way to do it. I wanted to add new Sub-Collection to existing document ID.I am new to android and Firestore. Thanks in advance.this is my Database
i tried this method but stuck couldn't succed
private void setNewCategory(String downloadUrl){
FirebaseFirestore db = FirebaseFirestore.getInstance();
DocumentReference newMainCatRef = db
.collection("HomeFeed")
.document("5HEkE0ac7sMa7Gjnvf3E")
.collection("MainCategory")
.document();
itemId = newMainCatRef.getId();
MainCategory category = new MainCategory();
category.setCategory_id(itemId);
category.setCategory_name(category_name.getText().toString());
category.setCategory_url(downloadUrl);
category.setPriority(priority.getValue());
newMainCatRef.set(category).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "onSuccess: Success on Updating the new Field to cat");
FirebaseFirestore NC = FirebaseFirestore.getInstance();
CollectionReference NewCategory = NC
.collection("Categories")
.document("tUdFCajDcQT995jX6G4k")
.collection(category_name.getText().toString());
NewCategory.add()
category_name.setText("");
priority.setValue(0);
category_image.setImageResource(R.drawable.ic_android);
category_progress.setVisibility(View.INVISIBLE);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(mContext, "Failed to add New Catgory Try again!", Toast.LENGTH_SHORT).show();
}
});
}
There is no need to make something special. As I see in your code, you're already using the right reference:
CollectionReference NewCategory = NC
.collection("Categories")
.document("tUdFCajDcQT995jX6G4k")
.collection(category_name.getText().toString());
category_name.getText().toString() being the name of the sub-collection but the problem rises in the following line of code:
NewCategory.add()
Where you aren't passing anything as an argument. You should pass a custom object or a Map in order to be able to write something in the database.
I need to update entries when a document already exists in FirebaseFirestore here is my code
call.enqueue(new Callback<DoctorsResponse>() {
#Override
public void onResponse(#NonNull Call<DoctorsResponse> call, #NonNull Response<DoctorsResponse> response) {
progressDialog.setTitle("Uploading...");
progressDialog.show();
if (response.isSuccessful()){
Log.e("##Success", String.valueOf(response.body().getData()));
docDetailsList.addAll(response.body().getData().getMemberData());
MemberDatum memberDatum = new MemberDatum();
for (int i =0; i<response.body().getData().getMemberData().size(); i++){
String queryforbranch = FirebaseFirestore.getInstance().collection("BranchWiseList").document().getId();
memberDatum.setDoctorId(queryforbranch);
memberDatum.setMbbsCollegeName(docDetailsList.get(i).getMbbsCollegeName());
memberDatum.setMbbsYear(docDetailsList.get(i).getMbbsYear());
memberDatum.setId(docDetailsList.get(i).getId());
memberDatum.setWuid(docDetailsList.get(i).getWuid());
memberDatum.setDocName(docDetailsList.get(i).getDocName());
memberDatum.setDocFatherName(docDetailsList.get(i).getDocFatherName());
memberDatum.setDocbloodGroup(docDetailsList.get(i).getDocbloodGroup());
memberDatum.setDocAddress(docDetailsList.get(i).getDocAddress());
memberDatum.setDocDistrict(docDetailsList.get(i).getDocDistrict());
memberDatum.setDocState(docDetailsList.get(i).getDocState());
memberDatum.setDocPrimaryMob(docDetailsList.get(i).getDocPrimaryMob());
memberDatum.setDoctDesignation(docDetailsList.get(i).getDoctDesignation());
memberDatum.setDocEmail(docDetailsList.get(i).getDocEmail());
memberDatum.setRmcNumber(docDetailsList.get(i).getRmcNumber());
memberDatum.setImaMember(docDetailsList.get(i).getImaMember());
memberDatum.setDocPopularName(docDetailsList.get(i).getDocPopularName());
memberDatum.setRmcRegistrationDate(docDetailsList.get(i).getRmcRegistrationDate());
memberDatum.setDocDob(docDetailsList.get(i).getDocDob());
memberDatum.setBranch(docDetailsList.get(i).getBranch());
memberDatum.setDateOfMarriage(docDetailsList.get(i).getDateOfMarriage());
memberDatum.setDocCity(docDetailsList.get(i).getDocCity());
memberDatum.setDocSpeciality(docDetailsList.get(i).getDocSpeciality());
memberDatum.setDocgender(docDetailsList.get(i).getDocgender());
memberDatum.setDoctCategory(docDetailsList.get(i).getDoctCategory());
memberDatum.setDoctImage(docDetailsList.get(i).getDoctImage());
memberDatum.setEmployeetype(docDetailsList.get(i).getEmployeetype());
memberDatum.setHospitalAbout(docDetailsList.get(i).getHospitalAbout());
memberDatum.setHospitalAddress(docDetailsList.get(i).getHospitalAddress());
memberDatum.setHospitalDistrict(docDetailsList.get(i).getHospitalDistrict());
memberDatum.setHospitalEmail(docDetailsList.get(i).getHospitalEmail());
memberDatum.setHospitalImageOne(docDetailsList.get(i).getHospitalImageOne());
memberDatum.setHospitalImageTwo(docDetailsList.get(i).getHospitalImageTwo());
memberDatum.setHospitalImageThree(docDetailsList.get(i).getHospitalImageThree());
memberDatum.setHospitalImageFour(docDetailsList.get(i).getHospitalImageFour());
memberDatum.setHospitalImageFive(docDetailsList.get(i).getHospitalImageFive());
memberDatum.setHospitalImageSix(docDetailsList.get(i).getHospitalImageSix());
memberDatum.setHospitalName(docDetailsList.get(i).getHospitalName());
memberDatum.setHospitalPhone(docDetailsList.get(i).getHospitalPhone());
memberDatum.setHospitalSpecilities(docDetailsList.get(i).getHospitalSpecilities());
memberDatum.setHospitalState(docDetailsList.get(i).getHospitalState());
memberDatum.setHospitalWebsite(docDetailsList.get(i).getHospitalWebsite());
memberDatum.setIsIMAMember(docDetailsList.get(i).getIsIMAMember());
memberDatum.setHospitalWebsite(docDetailsList.get(i).getHospitalWebsite());
memberDatum.setAddSpecialityModels(docDetailsList.get(i).getAddSpecialityModels());
memberDatum.setOrganizationModels(docDetailsList.get(i).getOrganizationModels());
memberDatum.setSuperSpecialityModels(docDetailsList.get(i).getSuperSpecialityModels());
Log.e("##Docname",docDetailsList.get(i).getDocName() );
FirebaseFirestore.getInstance().collection("BranchWiseList").document(memberDatum.getDoctorId()).set(memberDatum).addOnCompleteListener(task -> {
if (task.isSuccessful()) {
progressDialog.dismiss();
} else {
Toast.makeText(ImportBranchWise.this, "Something went wrong", Toast.LENGTH_SHORT).show();
}
});
When I would hit Api again I got double entries with different document id it is not updating I have tried with update queries already, help me I would appreciate every response on StackOverflow thank you in advance
you can use update instead of set since you always use the id anyway.
String queryforbranch = FirebaseFirestore.getInstance().collection("BranchWiseList").document().getId();
I do not know exactly what document you get when you do this, but it seems like you get the same one every time. I believe you need to save the id's of the documents somewhere else or just call get() instead of document() to get all the documents in your collection.
for example:
FirebaseFirestore.getInstance().collection("BranchWiseList")
.get().addOnCompleteListener(task -> {
if(task.isSuccessful()){
QuerySnapshot querySnapshot = task.getResult();
assert querySnapshot != null;
for (DocumentSnapshot documentSnapshot:
querySnapshot.getDocuments()) {
documentSnapshot.getID()
// here you can get everything done with the id.
}
}
});
I am using Cloud Firestore in my Android app. It's a quiz application where I randomly get documents from Firestore. When the internet connection is good, the app works fine. When the network gets disconnected and then again gets connected, I am unable to read the documents. When I debug, I find that my get() method is not getting executed at all.
Iterator iterator = randomIds.iterator();
while (iterator.hasNext()) {
String documentId = (String) iterator.next();
DocumentReference documentReference = db.collection(categoryName).document(documentId);
if (documentReference!=null) {
documentReference.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
System.out.println("Task successful");
DocumentSnapshot document = task.getResult();
questionDetailsObj = new QuestionDetails();
questionDetailsObj = document.toObject(QuestionDetails.class);
if (questionDetailsObj != null) {
System.out.println("Question details: " + questionDetailsObj.getQuestion_text());
// Adding the questions to a list
questionsList.add(questionDetailsObj);
}
} else {
Log.d("MainActivity", "get() failed with " + task.getException());
}
}
});
}
}
I want to retrieve 10 documents. Sometimes, few documents are retrieved successfully and for the others I get the exception
get() failed with com.google.firebase.firestore.FirebaseFirestoreException:
Failed to get document because the client is offline.
I don't understand why would some documents come successfully and some fail to get retrieved. Please help me understand if any code changes are required.
Inside a app, users will upload slot results with period name to the Parse Database. However, before upload, it would be much preferred if beforesave, checked whether the period ref is already there, if the same period ref is existing in the DB, the slot result would not be uploaded.
Cloud.beforesave
Parse.Cloud.beforeSave("check_duplicate", function(request, response)
{
var DB = Parse.Object.extend("Record_db");
var query = new Parse.Query(DB);
query.equalTo("period_ref", request.object.get("period_ref"));
query.first
({
success: function(object)
{
if (object)
{
response.error("A Period with this ref already exists.");
}
else
{
response.success();
}
},
error: function(error)
{
response.error("Could not validate uniqueness for this period ref object.");
}
});
});
Android code:
ParseCloud.callFunctionInBackground("check_duplicate", new HashMap<String, Object>(), new FunctionCallback<String>() {
public void done(String result, ParseException e)
{
if (e == null)
{
Utilities.custom_toast(CurrentResult.this, "cloud success" + result, "gone!", "short");
}
else
{
Utilities.custom_toast(CurrentResult.this, "cloud error" + e, "gone!", "short");
}
}
});
Question:
There is no clear example for such common situation. I would like to ask
for example, now the user would like to upload slot ref 001/2015 results. All info are already available at device, how could I pass this period reference 001/2015 to the cloud code for checking whether it is already existing in the Cloud DB uploading and saving to the Cloud DB?
Thanks a lot!
your first line of Android...
ParseCloud.callFunctionInBackground("check_duplicate", new HashMap(), new FunctionCallback() {
becomes
ParseCloud.callFunctionInBackground("check_duplicate",
new HashMap<String, String>{"period_ref":"001/2015"};,
new FunctionCallback<String>() {