Android Java Firebase Сохранить данные как карту - PullRequest
0 голосов
/ 14 июля 2020

Я пытаюсь сохранить точку пользователей на мою базу данных. Это изображение - то, что я хочу.

ожидаемая структура базы данных

Я хочу добавить результаты моих пользователей, например карту. Это мой код ниже, как я вызываю свои методы.

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();
                  }
            });
     }
});

Это мои методы.

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);
            }
        });

    }

Когда я пытаюсь сделать это, я не могу сохранить свой новый результат, он будет перезапись. Как я могу получить БД, как на моем изображении. Пожалуйста, помогите мне, как это сделать. Большое спасибо всем.

1 Ответ

1 голос
/ 14 июля 2020

Проблема в том, что для сохранения структуры, которую вы имеете в виду, вам придется обновить весь документ в хранилище.

Таким образом, идеальный поток вашего приложения должен быть для выполнения get(), чтобы получить полный документ, который уже существует в виде карты, добавьте свой новый счет на карту и затем обновите его. Вы можете сделать это, изменив свою функцию saveUserScoreToFirebase на следующую:

РЕДАКТИРОВАТЬ: Согласно нашему разговору в чате, вы хотите добавить дополнительное поле в эту коллекцию, которое называется gameTime, и у вас есть функция, которая получает объект модели игры, который содержит как gameResults, так и gameTime, и превращает его в json, что упрощает нашу жизнь, потому что все, что вам нужно сделать, это добавить этот json на карту перед ее обновлением. Обратите внимание, что все пункты, о которых я говорил ранее, по-прежнему действительны, поэтому код будет выглядеть так:

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);
            }
        });

    }
}

ПРИМЕЧАНИЕ : это не проверено, но должно быть хорошей отправной точкой для вас. рассмотрите описанный ранее logi c, если он не работает сразу.

...