Android 从Firebase数据库获取数据后更新UI
我有一个Firebase数据库和用户数据。我有一个使用此方法的用户类:Android 从Firebase数据库获取数据后更新UI,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,我有一个Firebase数据库和用户数据。我有一个使用此方法的用户类: private void getFromFirebase(){ final FirebaseDatabase database = FirebaseDatabase.getInstance(); DatabaseReference reference = database.getReference( FirebaseReferences.USERS ).child( userId ); ref
private void getFromFirebase(){
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference reference = database.getReference( FirebaseReferences.USERS ).child( userId );
reference.addValueEventListener( new ValueEventListener(){
@Override
public void onDataChange( @NonNull DataSnapshot dataSnapshot ){
display_name = dataSnapshot.child( "username" ).getValue( String.class );
photo = dataSnapshot.child( "profile_image" ).getValue( String.class );
}
@Override
public void onCancelled( @NonNull DatabaseError databaseError ){
}
} );
}
在MainActivity.java中,我想从数据库中获取配置文件照片,并将其显示在ImageView中。问题是Firebase是异步的,它会立即返回,所以我不能只调用myUser.getFromFirebase(),因为myUser仍将具有所有空值。我搜索了很多,但找不到解决方案,因为我根本不希望我的用户类与UI交互(我希望使用三层方法)
我尝试创建一个AsyncTask扩展类,但它也有同样的问题,因为问题出在用户类上。我还尝试了倒计时方法,但是由于该值已经存在于数据库中,因此onDataChange方法根本不会被调用
有人知道如何解决这个问题吗?我确信这非常容易,因为这不是一个奇怪的场景,但我太笨了…您必须安排您的视图在收到每个回调后更新到
onDataChange
。如果不希望回调直接修改视图,则需要采用某种形式的应用程序体系结构从视图中抽象出存储库(实时数据库)
这不是“非常容易”。此外,对于应用程序架构(MVP、MVC、MVVM)和各种框架(比如Android自己的LiveData),您有很多选择。您所从事的工作是非常固执己见的,并且需要编写比这里多得多的代码
我可以指出,Jetpack的Android架构组件是一个使用RTDB和Firestore的演示应用程序的应用程序架构,但你会看到它有很多代码行,这也是我对如何完成任务的看法。你会发现很多其他的观点。创建回调监听器,如下所示
public interface OnDataReceiveCallback {
void onDataReceived(String display_name, String photo);
}
修改方法以传递回调
private void getFromFirebase(OnDataReceiveCallback callback){
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference reference = database.getReference( FirebaseReferences.USERS ).child( userId );
reference.addValueEventListener( new ValueEventListener(){
@Override
public void onDataChange( @NonNull DataSnapshot dataSnapshot ){
display_name = dataSnapshot.child( "username" ).getValue( String.class );
photo = dataSnapshot.child( "profile_image" ).getValue( String.class );
callback.onDataReceived(display_name,photo);
}
@Override
public void onCancelled( @NonNull DatabaseError databaseError ){
}
});
}
getFromFirebase的最后一次调用
getFromFirebase(new OnDataReceiveCallback(){
public void onDataReceived(String display_name, String photo){
// do something
}
});
你考虑过占位符吗?空字符串、模拟图像等。。然后更新到正确的资产,当它通过。我用你的方法,并完成了工作!非常感谢!我在用户类中保留Firebase的做法是定义接口,并让用户的构造函数接受接口参数。然后,UI需要执行User User=new User(new InterfaceForCallback(){blah blah blah update UI with display_name and photo}),仅此而已。因此,UI不关心数据是本地的、在Firebase中的还是在任何其他存储中的。它只知道它需要一个回调函数来获取display_name和photo作为参数。你把它解决得如此简单明了!我去看看仓库!非常感谢您的澄清!