我有一个包含用户数据的Firebase数据库。我有一个使用这种方法的User类:
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仍将具有所有null值。我进行了很多搜索,但找不到解决方案,因为我根本不希望User类与UI进行交互(我想使用3层方法)。
我尝试创建AsyncTask扩展类,但是它存在相同的问题,因为问题出在User类上。我也尝试了CountdownLatch方法,但是由于该值已经在数据库中,因此onDataChange方法根本不会被调用!
有人知道如何解决吗?我敢肯定这是非常容易的,因为这不是一个奇怪的场景,但是我很固执...
答案 0 :(得分:0)
您将需要安排在收到onDataChange
的每个回调时更新视图。如果您不希望回调直接修改视图,则需要采用某种形式的应用程序体系结构从视图中抽象存储库(实时数据库)。
这不是“极其简单”。另外,您可以在应用程序体系结构(MVP,MVC,MVVM)和各种框架(例如Android自己的LiveData)方面有很多选择。您所从事的工作具有很高的见解,涉及编写的代码比此处的要多得多。
我可以指出a repository,它使用Jetpack的Android体系结构组件作为同时使用RTDB和Firestore的演示应用程序的应用程序体系结构,但是您会看到它包含很多代码行,并且我对如何完成工作的看法。您还会在那里找到许多其他意见。
答案 1 :(得分:0)
创建回调侦听器,如下所示
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
}
});