将本地对象同步到 Firebase 实时数据库中存储的副本

问题描述 投票:0回答:1

我有一个简单的 Android 应用程序,其中使用 Firebase 实时数据库来存储登录用户的详细信息。

这是我存储在数据库中的用户对象:

public class User {

    private UserType userType;
    private String phoneNumber;
    private String fullName;
    private String email;

    // addresses are stored as HOSTEL.ROOMNUMBER format
    private String hostelAddress;

    public User(UserType userType, String phoneNumber, String fullName, String email, String hostelAddress) {
        this.userType = userType;
        this.phoneNumber = phoneNumber;
        this.fullName = fullName;
        this.email = email;
        this.hostelAddress = hostelAddress;
    }


    // required for realtime Database
    public User() {
    }

    // getters and setters for all fields...
}

每次用户成功登录(通过 Firebase Auth 验证)时,我都会创建一个 User 对象,并将其存储为针对用户 UID 的值(作为数据库中的键)。到这部分为止的一切都按预期进行。

看起来像这样:

{
  "users": {
    "<UID>": {
      "email": "<email>",
      "fullName": "<full name>",
      "hostelAddress": "<address>",
      "phoneNumber": "<number>",
      "userType": "CUSTOMER"
    }
  }
}

现在,我想要一个本地存储的用户对象,该对象与存储在与当前签名用户相对应的数据库中的用户对象同步。 我想在我的应用程序的不同活动中访问此用户对象。

为此,我创建了一个单独的类来与数据库交互:

abstract public class FirebaseUtil {

    public static FirebaseDatabase database;

    public static User currentUserObject;

    public static String getCurrentUserID()
    {
        return FirebaseAuth.getInstance().getUid();
    }

    public static DatabaseReference getCurrentUserReference()
    {
        return database.getReference("users").child(getCurrentUserID());
    }

    static
    {

        database = FirebaseDatabase.getInstance();
        fetchCurrentUser();

    }
     
    public static void fetchCurrentUser()
    {
        if (getCurrentUserID()==null)
        {
            return;
        }
        getCurrentUserReference().addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {

                currentUserObject = snapshot.getValue(User.class);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });
    }
   
   
    // Store user inside database, with the key as its UID.
    public static void storeUser(User user, String UID)
    {
        database.getReference("users").child(UID).setValue(user).addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                fetchCurrentUser();
            }
        });
    }
}

问题是这种方法不起作用,每当我尝试在应用程序的另一个类中使用

currentUserObject
时,它总是
null
,即使
getCurrentUserID()
方法成功返回登录的用户UID。

我没有尝试过很多事情,因为我根本不知道为什么这不起作用。 我将感谢任何朝着正确方向的推动。

如果有更好、更可靠的方法来完成这项任务,请告诉我。

java android firebase asynchronous firebase-realtime-database
1个回答
0
投票

正如 @FrankvanPuffelen 在他的评论中已经提到的,这个问题很可能与 Firebase 加载数据的方式有关,这是异步的。我建议的是,不要在应用程序的每个活动中访问

fetchCurrentUser()
方法,只需在应用程序启动时创建对实时数据库的单个调用,等待读取数据的操作完成,将用户对象添加到意图并向前导航到另一个活动。

是的,永远不要忽视潜在的错误。因此,请务必通过抛出错误来检查

onCancelled()
方法内的错误消息:

throw databaseError.toException();

或者通过记录错误消息:

Log.d("TAG", error.getMessage());
© www.soinside.com 2019 - 2024. All rights reserved.