Обновления Firebase Multipath перезаписывают, а не обновляют потомки - PullRequest
0 голосов
/ 24 июня 2018

Я использую базу данных Firebase в реальном времени в своем приложении для Android.В целях нормализации данных я сохраняю данные игрока по нескольким путям.Когда я сохраняю его для каждого пути отдельно, все работает нормально.Но я попытался сохранить данные, используя обновление Multiple-Path, и затем вместо обновления существующих дочерних элементов это перезаписывает существующие данные (как в 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 и смог решить эту проблему.

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

1 Ответ

0 голосов
/ 24 июня 2018

Обновление для нескольких местоположений проходит по каждому ключу в 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...