Vince Ybañez
Vince Ybañez

Reputation: 113

How to run multiple batched write in Firestore asynchronously in Android?

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

Answers (1)

Alex Mamo
Alex Mamo

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

Related Questions