Android Firebase为空 [英] Android firebase getting null

查看:59
本文介绍了Android Firebase为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Firebase保存我的数据.我正在尝试将Firebase方法和活动中的方法分开.例如,我创建了一个名为"FirebaseMethodsHelper"的类,在那里我想编写所有Firebase方法. 例如,应在列表中返回所有用户的"getAllUsers"方法. 我唯一的问题是它无法正常工作.

I'm using Firebase to save my data. I'm trying to separate Firebase methods and my methods on the activity. For example i have created class that called "FirebaseMethodsHelper" and there i want to write all the Firebase methods. For example, "getAllUsers" method that should return in list all the users. The only problem i have that it does not working.

我不知道我在做什么错,所以如果你们请可以帮助我.

I dont know what im doing wrong, so if you guys please can help me.

片段

  public class MyPlayListFragment extends Fragment {
    private FirebaseDatabase refToVideos;
    private FirebaseUser currentUser;
    private ArrayList<Video> videosList;
    private VideoViewAdapter adapter;
    private RecyclerView rvVideos;
    private List<Video> checkList;


public MyPlayListFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_my_play_list, container, false);
    rvVideos = (RecyclerView)v.findViewById(R.id.rvVideos);

    return v;
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    videosList = new ArrayList<>();
    refToVideos = FirebaseDatabase.getInstance();
    currentUser = FirebaseAuth.getInstance().getCurrentUser();

    FirebaseMethodsHelper fmh = new FirebaseMethodsHelper();


    checkList = fmh.getAllVideosFromDB(currentUser);
    if(checkList != null)
    Log.d("checkList",checkList.toString());

FirebaseMethodHelper类

   public class FirebaseMethodsHelper {
private FirebaseDatabase databaseRef;
private ArrayList<User> usersList;
private ArrayList<Video> videosList;



   public List<Video> getAllVideosFromDB(FirebaseUser currentUser){
        databaseRef = FirebaseDatabase.getInstance();
        databaseRef.getReference(Params.VIDEOS).child(currentUser.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot snapshot : dataSnapshot.getChildren()){
                    videosList.add(snapshot.getValue(Video.class));
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });


    return videosList;
  }
 }

我不知道为什么,但是它总是返回null.

I dont know why, but it always return null.

推荐答案

这是异步Web API的经典问题:您无法返回尚未加载的 now 内容.

This is a classic problem with asynchronous web APIs: you cannot return something now that hasn't been loaded yet.

Firebase数据库(和大多数现代的Web API)数据是异步加载的,因为它可能需要一些时间.无需等待数据(这将导致用户出现应用程序无响应"对话框),而是在将数据加载到辅助线程上时继续使用主应用程序代码.然后,当数据可用时,您的onDataChange()方法将被调用并可以使用该数据.

Firebase Database (and most modern web APIs) data is loaded asynchronously, since it may take some time. Instead of waiting for the data (which would lead to Application Not Responding dialogs for your users), your main application code continues while the data is loaded on a secondary thread. Then when the data is available, your onDataChange() method is called and can use the data.

这会更改您的应用程序的流程.最简单的方法是放置一些日志语句:

This changes the flow of your app. The easiest way to see this is by placing a few log statements:

public List<Video> getAllVideosFromDB(FirebaseUser currentUser){
    databaseRef = FirebaseDatabase.getInstance();
    System.out.println("Before attaching listener");
    databaseRef.getReference(Params.VIDEOS).child(currentUser.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            System.out.println("Got data");
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            throw databaseError.toException(); // don't ignore errors
        }
    });
    System.out.println("After attaching listener");
}

运行此代码将打印以下序列:

Running this code will print the following sequence:

在附加侦听器之前

Before attaching listener

附加监听器后

获得数据

这可能不是您所期望的,但恰恰说明了为什么返回数组时该数组为空.

This is probably not what you expected, but explains precisely why the array is empty when you return it.

对于大多数开发人员而言,最初的反应是尝试并修复"程序.这种异步行为.我反对这样做:Web是异步的,您越早接受它,您就越早学会如何使用现代Web API变得高效.

The initial response for most developers is to try and "fix" this asynchronous behavior. I recommend against that: the web is asynchronous, and the sooner you accept that, the sooner you can learn how to become productive with modern web APIs.

我发现最容易重新构造这种异步范例的问题.与其说首先获取所有视频,然后记录它们",不如说是开始获取所有视频"的问题.加载视频后,将其记录为.

I've found it easiest to reframe problems for this asynchronous paradigm. Instead of saying "First get all videos, then log them", I frame the problem as "Start getting all videos. When the videos are loaded, log them".

这意味着任何需要视频的代码都必须在onDataChange()内部(或从内部调用).例如:

This means that any code that requires the video must be inside onDataChange() (or called from inside there). E.g.:

public List<Video> getAllVideosFromDB(FirebaseUser currentUser){
    databaseRef = FirebaseDatabase.getInstance();
    databaseRef.getReference(Params.VIDEOS).child(currentUser.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot snapshot : dataSnapshot.getChildren()){
                videosList.add(snapshot.getValue(Video.class));
            }
            if (videosList != null) {
                Log.d("checkList",videosList.toString());
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            throw databaseError.toException(); // don't ignore errors
        }
    });

}

正如我所说,这对于以前从未处理过异步API的开发人员来说是一个普遍的问题.这样,已经有很多关于该主题的问题了,我建议您也将它们检出:

As I said, this is a common problem for developers who haven't dealt with asynchronous APIs before. As such, there have been quite some questions on the topic already, and I recommend you check them out too:

  • Setting Singleton property value in Firebase Listener
  • Handle data returned by an Async task (Firebase) (showing how to define and pass in your own callback)
  • Firebase - Android - fetchProvidersForEmail - Why are all the calls asynchronous? (with lots more links to other similar questions)

这篇关于Android Firebase为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆