Reputation: 606
In am creating a quiz app and when a player clicks on a certain button, it creates the new game in the database and opens the next activity (game activity). I am not sure which approach is the best way to set up new documents in the database.
Basically what I want to know is, which of the following approaches is the best way and am I am right with the assumptions. The goal is to find the best way to assure that the user only gets to the next activity when all documents got created.
I assume that this is faster than the second approach but has the risk that some documents/ sub-collections will not be created. (I have a lot more documents that are created but fir simplicity I just show some)
...
gameRef.document(gameId).collection("Uid").document("Uid").set(uidPlayers);
gameRef.document(gameId).collection("Turn").document("Turn").set(mTurn);
gameRef.document(gameId).collection("Game Status").document("Game Status").set(gameStatus);
gameRef.document(gameId).collection("Timestamp").document("Timestamp").set(timeStamp);
Intent i = new Intent(FriendDetailActivity.this, GameActivity.class);
startActivity(i);
...
This approach is safer than the first since it assures that every document /sub-collection will be created before the user exits this activity but it does take longer. Also I simplified the code here. It is safer, because after every creation I add an onCompleteListener.
...
gameRef.document(gameId).collection("Round").document("Round").set(round)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
db.collection("User").document(uidPlayer1).collection("Games").document(uidPlayer2).set(gameUser)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
db.collection("User").document(uidPlayer2).collection("Games").document(uidPlayer1).set(gameUser2)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
Intent i = new Intent(FriendDetailActivity.this, GameActivity.class);
startActivity(i);
}
});
}
});
}
});
...
Upvotes: 1
Views: 190
Reputation: 448
Doug's answer looks great.
If you don't want to batch write, you can also try using CompleteableFuture.allOf
instead of those nested callbacks.
Here's the API docs for it.
Upvotes: 1
Reputation: 317372
If you want to make sure all documents are written at the same time, use a batch write to create them all at the same time. There will be no need to check individual status. The batch will either happen all at the same time, or fail all at the same time.
WriteBatch batch = db.batch();
DocumentReference uidRef = gameRef.document(gameId).collection("Uid").document("Uid");
batch.set(uidRef, uidPlayers);
// add more documents...
batch.commit().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
// ...
}
});
Upvotes: 3