Reputation: 23
i'm tryin to save my users point to my firebase. This image is what i want.
I want to add my users results like map. This is my code below how i call my methods.
checkUserScoreIsExist(gameUser, new UserExistsCallback() {
@Override
public void onCallback(boolean isExisting) {
saveUserScoreToFirebase(gameUser, currentGame, isExisting,
new ScoreUserCallback() {
@Override
public void onCallback(boolean isScoreUserSaveSuccess) {
if(isScoreUserSaveSuccess)
Toast.makeText(GameActivity.this, "Score saved successfully", Toast.LENGTH_LONG).show();
else
Toast.makeText(GameActivity.this, "Score can not saved successfully", Toast.LENGTH_LONG).show();
}
});
}
});
These are my methods.
private void checkUserScoreIsExist(final User user, final UserExistsCallback callback) {
Log.d(TAG, "User score checking.");
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
DocumentReference docIdRef = rootRef.collection("scores").document(user.getUsername());
docIdRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
assert document != null;
isScoreExist = document.exists();
} else {
Log.d(TAG, "Failed with: ", task.getException());
}
callback.onCallback(isScoreExist);
}
});
}
private void saveUserScoreToFirebase(User user, Game game, boolean isScoreExist, final ScoreUserCallback callback) {
Log.d(TAG, "Saving user to database.");
Map<String, Object> gameMap = new HashMap<>();
gameMap.put("gameResult", game.calculateResult());
if(isScoreExist){
db.collection("scores").document(user.getUsername())
.update(gameMap).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
isSaveScoreSuccess = task.isSuccessful();
callback.onCallback(isSaveScoreSuccess);
}
});
}else{
db.collection("scores").document(user.getUsername())
.set(gameMap).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
isSaveScoreSuccess = task.isSuccessful();
callback.onCallback(isSaveScoreSuccess);
}
});
}
When i try like this i can not save my new result it is gonna be overwriting. How can i obtain db like in my image. Please help me how to do that. Many thanks everyone.
Upvotes: 0
Views: 190
Reputation: 5829
The problem is that, in order to keep the structure you have in mind, you will have to update the whole document to the firestore.
So the ideal flow of your app should while updating score should be to perform a get()
to get the complete document that is already in there as a map, add your new score to the map and then update it. You can do that by changing your saveUserScoreToFirebase
function to the following:
EDIT: As per our conversation in the chat, you want to add an extra field to that collection as well, that is called gameTime, and you have a function that get the game model object, that contains both gameResults and gameTime, and makes it into a json, which simplifies our lifes cause all you need to do is add that json to the map before updating it. Note that all the points I made before are still valid, so the code will look like this:
private void saveUserScoreToFirebase(User user, Game game, boolean isScoreExist, final ScoreUserCallback callback) {
Log.d(TAG, "Saving user to database.");
Map<String, Object> gameMap = new HashMap<>();
if(isScoreExist){
db.collection("scores").document(user.getUsername())
.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
// Document found in the offline cache
DocumentSnapshot document = task.getResult();
gameMap = document.getData();
// if you are starting with # 0 you can take the '+1' from this
gameMap.put(String.valueOf(gameMap.size()+1), game.toJSON());
db.collection("scores").document(user.getUsername())
.update(gameMap).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
isSaveScoreSuccess = task.isSuccessful();
callback.onCallback(isSaveScoreSuccess);
}
});
} else {
Log.d(TAG, "Getting previous score failed with following exception: ", task.getException());
}
}
});
}else{
gameMap.put(String.valueOf(gameMap.size()+1), game.toJSON());
db.collection("scores").document(user.getUsername())
.set(gameMap).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
isSaveScoreSuccess = task.isSuccessful();
callback.onCallback(isSaveScoreSuccess);
}
});
}
}
NOTE: This is untested but should be a good starting point for you to consider the logic described earlier if it does not work right away.
Upvotes: 1