Обновления Firebase Multipath перезаписываются вместо дочерних обновлений

Я использую базу данных Firebase в реальном времени в своем приложении для Android. Для нормализации данных я сохраняю данные игрока по нескольким путям. Когда я сохраняю его для каждого пути отдельно, все работает нормально. Но я попытался сохранить данные с помощью обновления с несколькими путями, а затем вместо обновления существующих дочерних элементов это перезаписывает существующие данные (как в setValue). Я где-то читал об этом явлении, но не могу заставить его работать должным образом.

Вот соответствующий фрагмент моего кода:

public void createPlayerInFirebaseDatabse(String playerId, FirebasePlayerEntity firebasePlayerEntity, final ICreateUser listener) {

    Log.e(TAG, "DBHelper.createPlayerInFirebaseDatabase");

    Map<String, Object> player = new HashMap<>();
    player.put(playerId, firebasePlayerEntity);

    Map<String, Object> isPlayerIn = new HashMap<>();
    isPlayerIn.put(playerId, true);

    Map<String, Object> playerUpdates = new HashMap<>();
    playerUpdates.put("players/", player);
    playerUpdates.put("leagues/" + firebasePlayerEntity.getLeagueCode() + "/playersIds/", isPlayerIn);
    playerUpdates.put("teams/" + firebasePlayerEntity.getTeam() + "/playersIds", isPlayerIn);
    databaseReference.updateChildren(playerUpdates)

            .addOnCompleteListener(new OnCompleteListener<Void>() {
        @Override
        public void onComplete(@NonNull Task<Void> task) {
            if (task.isSuccessful()) {
                Log.e(TAG, "DBHelper.createPlayerInFirebaseDatabase: onSuccess");
                listener.onSuccess();
            } else {
                listener.onError(ErrorConsts.ERROR_CODE_DB_WRITING_FAILED);
            }
        }
    });

Он только обновляет данные (не перезаписывая), когда я сохраняю данные отдельно для каждого пути, например:

databaseReference.child(REF_PLAYERS).updateChildren(player);
databaseReference.child(REF_LEAGUES + "/" + firebasePlayerEntity.getLeagueCode() + "/" + REF_PLAYERS_IDS).updateChildren(isPlayerIn);
databaseReference.child(REF_TEAMS + "/" + firebasePlayerEntity.getTeam() + "/" + REF_PLAYERS_IDS).updateChildren(isPlayerIn)

Нашел эту тему на javascript Перезапись обновления Firebase с несколькими местоположениями вместо обновления значения но мне было интересно, испытал ли кто-нибудь это на Android и смог ли решить эту проблему.

Любая помощь будет оценена по достоинству. Благодарность!

0
0
211
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обновление с несколькими местоположениями проходит по каждому ключу в Map, который вы передаете, и выполняет setValue на этом пути. Он не выполняет «глубокого слияния», поэтому все, что находится под любым ключом на вашей карте, будет заменено. По этой причине вам необходимо убедиться, что пути на вашей карте соответствуют точным данным, которые вы хотите заменить.

Прямо сейчас ваши ключи карты указывают на один уровень выше. Например, на ваших картах указано обновить players до $playeruid/<playerEntity>. Это означает, что вы заменяете все, что находится под players, данными для нового плеера, а это не то, что вам нужно. Вместо этого вы должны указать Firebase обновить players/$playeruid до <playerEntity>, таким образом сделав $playeruid частью пути / ключа.

В коде:

Map<String, Object> playerUpdates = new HashMap<>();
playerUpdates.put("players/" + playerId, firebasePlayerEntity);
playerUpdates.put("leagues/" + firebasePlayerEntity.getLeagueCode() + "/playersIds/" + playerId, true);
playerUpdates.put("teams/" + firebasePlayerEntity.getTeam() + "/playersIds/" + playerId, true);
databaseReference.updateChildren(playerUpdates)

Большое спасибо! теперь все работает как надо. Я ценю вашу помощь:)

Orit Malki 25.06.2018 08:36

Другие вопросы по теме