从Firebase数据库获取数据后更新UI

时间:2018-09-01 16:55:13

标签: android firebase firebase-realtime-database

我有一个包含用户数据的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方法根本不会被调用!

有人知道如何解决吗?我敢肯定这是非常容易的,因为这不是一个奇怪的场景,但是我很固执...

2 个答案:

答案 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
  }
});