Android Studio Java中如何将Firebase实时数据库数据存入类属性
问题根因
你的DataSnapshot用法没有错误,出现这个问题的核心原因是Firebase Realtime Database的读写操作都是异步执行的:
- 你在User构造方法中添加的
ValueEventListener不会立刻执行onDataChange回调,主线程会继续执行后续代码 - 你实例化User后立刻调用
getName()时,onDataChange还没被触发,name还保持初始的null值 - 等
onDataChange内的日志打印时,赋值操作才完成,此时再调用getName()才能拿到正确值,但你之前的Toast和日志逻辑已经执行完毕
解决方案
采用回调接口的方式,等用户数据加载完成后再执行后续的日志打印、Toast等逻辑:
步骤1:定义数据加载回调接口
public interface OnUserLoadedListener { // 数据加载成功回调 void onLoadSuccess(User user); // 数据加载失败回调 void onLoadFailed(DatabaseError error); }
步骤2:修改User类代码
public class User { private String uID; private String name; private String email; private DatabaseReference mdatabaseReference; public User(String givenUiD){ this.uID = givenUiD; mdatabaseReference = FirebaseDatabase.getInstance().getReference(); } // 新增用户数据加载方法,传入回调监听 public void loadUserData(OnUserLoadedListener listener) { // 如果仅需要一次性拉取数据,用addListenerForSingleValueEvent替代addValueEventListener,避免内存泄漏 mdatabaseReference.child("users").child(uID).addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { name = dataSnapshot.child("name").getValue(String.class); email = dataSnapshot.child("email").getValue(String.class); Log.d(TAG, "onDataChange: "+name); // 通知调用方加载完成 listener.onLoadSuccess(User.this); } @Override public void onCancelled(@NonNull DatabaseError error) { listener.onLoadFailed(error); } }); } public String getName(){ return this.name; } public String getEmail() { return this.email; } }
步骤3:修改signInFragment调用逻辑
currentUser = new User(mAuth.getCurrentUser().getUid()); currentUser.loadUserData(new OnUserLoadedListener() { @Override public void onLoadSuccess(User user) { // 仅在加载成功回调中才能拿到正确的用户属性 Log.d(TAG, "onComplete: " + user.getName()); Toast.makeText(getContext(),"Log in successful.Welcome "+ user.getName(),Toast.LENGTH_SHORT).show(); // 后续页面跳转、数据刷新等逻辑都放在这里执行 } @Override public void onLoadFailed(DatabaseError error) { // 自定义加载失败处理逻辑 Log.e(TAG, "加载用户数据失败", error.toException()); Toast.makeText(getContext(), "加载用户信息失败,请重试", Toast.LENGTH_SHORT).show(); } });
内容的提问来源于stack exchange,提问作者yt.
相关产品推荐
相关产品推荐

