Why this error : java.lang.IllegalStateException: A write batch can no longer be used after commit() has been called

Viewed 1337

The the following code i am trying to delete a member, a member should be deleted with his details and all his fees records.

 public void deleteMember(Member member) {
    final WriteBatch batch = FirebaseFirestore.getInstance().batch();
    DocumentReference memberDoc = getMemberReference().document(member.getMemberId());
    batch.delete(memberDoc);
             getFeeReference().whereEqualTo("id", member.getMemberId())
            .get()
            .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                @Override
                public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                    for(QueryDocumentSnapshot snapshot : queryDocumentSnapshots){
                        batch.delete(snapshot.getReference()); // this is the line of error
                    }
                }
            });
    batch.commit();
    getMemberImagesReference().child(member.getMemberId() + "t.jpg").delete();
    getMemberImagesReference().child(member.getMemberId() + "f.jpg").delete();
}

But i am getting the following error

 2020-04-10 22:57:33.462 29454-29454/com.abhinav.chauhan.gymdatamanager D/AndroidRuntime: Shutting 
 down VM
 2020-04-10 22:57:33.464 29454-29454/com.abhinav.chauhan.gymdatamanager E/AndroidRuntime: FATAL 
 EXCEPTION: main
 Process: com.abhinav.chauhan.gymdatamanager, PID: 29454
 java.lang.IllegalStateException: A write batch can no longer be used after commit() has been called.
    at com.google.firebase.firestore.WriteBatch.verifyNotCommitted(com.google.firebase:firebase- 
     firestore@@21.4.2:202)
    at com.google.firebase.firestore.WriteBatch.delete(com.google.firebase:firebase- 
    firestore@@21.4.2:179)
    at 
    com.abhinav.chauhan.gymdatamanager.database.FireBaseHandler$1.onSuccess(FireBaseHandler.java:110)
    at    
    com.abhinav.chauhan.gymdatamanager.database.FireBaseHandler$1.onSuccess(FireBaseHandler.java:106)
    at com.google.android.gms.tasks.zzn.run(Unknown Source:4)
    at android.os.Handler.handleCallback(Handler.java:808)
    at android.os.Handler.dispatchMessage(Handler.java:101)
    at android.os.Looper.loop(Looper.java:166)
    at android.app.ActivityThread.main(ActivityThread.java:7425)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
1 Answers

get() is asynchronous and returns immediately before the query is complete. Your code will go on after that to commit the batch with a single delete in it. Some time later, after the get() finishes, your code then attempts to add another delete to the batch, after it was completed. That's why you get the error - the batch can't be modified again after you call commit().

Perhaps you should wait until your callback is invoked before adding all the documents to modify and calling commit(), in order to ensure that commit() is the last method invoked on the batch.

Related