web-dev-qa-db-ja.com

Android Firebaseは一部のフィールドのみを更新します

私はAndroidアプリを開発しており、ユーザーがこのアプリを起動するたびに、既存のデータと私のアプリを更新すると、このユーザーから新しいレジスタ(存在しない場合)が生成されますユーザーノードにさらに情報を挿入します。

このノードを更新するたびに、他のすべての情報が失われます。

私のユーザークラス

_@IgnoreExtraProperties
public class User {

public String userID;
public String userName;
public String userMail;
public boolean active;

    public User() {}

    public User(String userID, String userName) {
        this.userID = userID;
        this.userName = userName;
    }

    public User(String userID, String userName, String userMail, boolean active) {
        this.userID = userID;
        this.userName = userName;
        this.userMail = userMail;
        this.active = active;

    }

    @Exclude
    public Map<String, Object> toMap() {
        HashMap<String, Object> result = new HashMap<>();
        result.put("user_id", userID);
        result.put("name", userName);
        result.put("email", userMail);
        result.put("active", active);

        return result;
   }

}
_

そして私の更新コード:

_public class FireBaseUser {
    public static String FB_REFERENCE_USER = "user";

    public void updateUser(String userID, String userName, String userMail, boolean userActive) {
        // Write a message to the database
        FirebaseDatabase database = FirebaseDatabase.getInstance();
        DatabaseReference myRef = database.getReference(FB_REFERENCE_USER);


        User user = new User(userID, userName, userMail, userActive);
        Map<String, Object> postValues = user.toMap();

        Map<String, Object> childUpdates = new HashMap<>();
        childUpdates.put(userID, postValues);

        myRef.updateChildren(childUpdates);

    }
}
_

myRef.updateChildren(childUpdates);を呼び出すと、古いデータがすべて更新され、新しい子(アプリで作成したもの)が失われます。

enter image description here

12
rodrigo

更新を実行している参照は、パスFB_REFERENCE_USER-ユーザーを含むパスのようです。

updateChildrenは、直接の子のみを更新し、それらの下の値は置き換えられます。したがって、更新ではユーザーの子全体が置き換えられ、他のユーザーの子はそのまま残ります。それが予想される動作です。

特定のユーザーのrefを使用して更新を実行する必要があります。これにより、更新されていないそのユーザーのプロパティは変更されません。

つまり、次のようにする必要があります。

User user = new User(userID, userName, userMail, userActive);
Map<String, Object> postValues = user.toMap();
myRef.child(userID).updateChildren(postValues);

updateChildrenの動作については、ドキュメントの here で説明されています。

11
cartant

一部のフィールドのみを更新したい場合は、

myRef.child(userID).child("which field do you want to update").setValue(ValueVariable);

はい、他の既存のデータを失うことなく、単一ノードを更新できます。

pojoを作成し、既存のノードで更新する値を設定して、そのpojoオブジェクトをsetValue(pojo)メソッドに送信する必要があります。

例えば:

User updatedUser=new User();
updatedUser.setName("Rishabh");
updatedUser.SetEmail("[email protected]");
myref.setValue(updatedUser);

PS:myrefは、データを更新するuser idノードまでの参照です。

1
rishabh

マップを使用して同じことを行うことができます...

    String active = "true";
    String email = "[email protected]";
    String name = "your name";
    String user_id = "user_id";

    // HashMap For Updating Data
    HashMap<String, Object> updateFbDb = new HashMap<>();
    updateFbDb.put("active", active);
    updateFbDb.put("email", email);
    updateFbDb.put("name", name);
    updateFbDb.put("user_id", user_id);

    fbDbRefRoot.child("user").child(currentUserId).updateChildren(updateFbDb).addOnSuccessListener(new OnSuccessListener<Void>() {
        @Override
        public void onSuccess(Void aVoid) {

            // Done

        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {

            Log.d(TAG, "fbSetValueFailure: " + e.getMessage());

        }
    });
0
DragonFire