Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 从Firebase数据库获取数据后更新UI_Android_Firebase_Firebase Realtime Database - Fatal编程技术网

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

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

我有一个Firebase数据库和用户数据。我有一个使用此方法的用户类:

    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作为参数。你把它解决得如此简单明了!我去看看仓库!非常感谢您的澄清!