Reputation: 113
I'm using Android-Java and Firestore. I want to run multiple batched writes asynchronously so that if 1 batch write fails, all write batches must also fail. This is what I did,
btn_batch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CollectionReference facultyRef = db.collection("Faculty");
List<WriteBatch> writeBatches = new ArrayList<>();
writeBatches.add(db.batch());
int counter = 0, batchIndex = 0;
for(int i=1; i<=10000; i++){
String username = "user"+i;
String password = UUID.randomUUID().toString().substring(0, 7);
User user = new User(username, password);
writeBatches.get(batchIndex).set(facultyRef.document(), user);
counter++;
if(counter == 499){
writeBatches.add(db.batch());
counter = 0;
batchIndex++;
}
}
commitBatches(writeBatches);
}
});
private void commitBatches(List<WriteBatch> writeBatches){
if(writeBatches.size() > 0){
WriteBatch writeBatch = writeBatches.get(0);
writeBatch.commit()
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull @NotNull Task<Void> task) {
if(task.isSuccessful()){
writeBatches.remove(0);
commitBatches(writeBatches);
}else{
Toast.makeText(MainActivity.this, task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}else{
Toast.makeText(this, "Batched Write Success", Toast.LENGTH_SHORT).show();
}
}
My problem is that this code is not asynchronous therefore this code performs very slow and not reliable. Is there any way to run this code asynchronously? Please help me.
Upvotes: 0
Views: 133
Reputation: 138824
The batch operation is by definition atomic. This means that all operations succeed, or none of them are applied.
As I understand from your question, you need a batch of batches, which is actually not possible. If you have 500 operations in a batch and another 500 operations in another batch, those operations are considered atomic but separately. You cannot merge 1.000 operations in a single batch.
Edit:
WriteBatch#commit() method returns an object of type Task<Void>
. This means that you can do something like this:
Task firstTask = firstWriteBatch.commit();
Task secondTask = secondWriteBatch.commit();
Task combinedTask = Tasks.whenAllSuccess(firstTask, secondTask).addOnSuccessListener(/* ... /*);
Or you can pass a list of Task objects.
Upvotes: 1