这个问题已经在这里有了答案: > How to return DataSnapshot value as a result of a method? 4个
我是Firebase Realtime数据库的新手.我正在开发一个AndroID应用,该应用需要从Firebase Realtime DB检索数据.在大多数情况下,我已经能够使用Firebase侦听器方法检索数据,但有一次,我发现它无法以我想要的方式获得值(我认为是由于异步的性质).
场景: –
我在Firebase实时数据库中有一个数据结构,如下所示:
评分:
对于用户:
我有一个单独的java类(Suggest.java),该类具有一个简单的方法来获取用户列表(此处未显示,因为它是基本的实现),下面定义的方法是从上述评级节点中检索数据到列表:
public List<String> getMyUnratedposts(final String currentUserID){ final List<String> currentUserUnratedposts = new ArrayList<>(); DBRCurrentUnratedList = FirebaseDatabase.getInstance().getReference().child("adrat").child(currentUserID); DBRCurrentUnratedList.addValueEventListener(new ValueEventListener() { @OverrIDe public voID onDataChange(DataSnapshot dataSnapshot) { for (DataSnapshot snapshot : dataSnapshot.getChildren()) { Adrat adr = snapshot.getValue(Adrat.class); int vr = adr.getVIEwrating(); if(vr < 1) { currentUserUnratedposts.add(adr.getAdID()); } } } @OverrIDe public voID onCancelled(DatabaseError databaseError) { } }); return currentUserUnratedposts;}
上面定义的Adrat类只是具有与上面给出的数据库节点匹配的属性(以及getter和setter)的类.
我正在活动的onCreate()方法中创建此类(Suggest.java)的实例.然后,首先调用一个仅获取用户列表的方法(与上述获得评分的方法非常相似).然后,在我的活动的下一行代码中,我使用一个for循环从所获得的列表中获取每个用户,并将该userID用于上面显示的方法.例如,如下所示:
Suggest sj = new Suggest();List<String> users = sj.getUsers();for (final String mUser: users) { //Just trying to use the user from above here List<String> myUnratedItems = sj.getMyUnratedposts(mUser); Log.d(TAG, "List contains : " + myUnratedItems.toString());}
问题:-
运行此程序时,我没有从代码中得到预期的结果.调试它时,用户列表将为null.我认为因为firebase方法是异步的,所以它们不会在下一行代码(即我需要的地方)中准确给出结果,而是稍后给出结果(但是程序已在代码行中运行)我需要这些数据).
我的整体需求:-
获取要在下一行代码中使用的用户列表(用于下一个方法).
我已经在Stackoverflow中解决了几个问题,但是找不到确切的答案.
请解释为什么会发生这种情况,以及任何解决方法.
附: :-我是stackoverflow的新手,所以请承担在撰写问题时犯下的任何错误.谢谢.
解决方法:
实际上,eventListener和对Firebase的调用具有异步行为,因此您已经正确理解了您的问题.
不幸的是,我拥有的解决方案(几乎可以肯定是可行的)是,因此您可能不得不更改方法.
因此,您应该采用事件驱动的方法.因此,您应该“当数据进入时,做我的事情”,而不是“等待数据来做我的事情”.
根据您的问题的含义,首先,您应该像在valueEventListener的onDataChange()中正确完成的 *** 作一样,从Firebase中检索用户列表,然后在其下面执行您打算做的事情.
问题在于,由于Firebase具有异步调用,因此在获取数据之前先打印出数据,如果您尚未将其初始化为其他内容,则显然为null.因此,您执行的所有其他 *** 作均在null上进行.
因此,最好在valueEventListener自身内部执行方法或代码.
在您给定的代码中是这样的:
public List<String> getMyUnratedposts(final String currentUserID){ final List<String> currentUserUnratedposts = new ArrayList<>(); DBRCurrentUnratedList = FirebaseDatabase.getInstance().getReference().child("adrat").child(currentUserID); DBRCurrentUnratedList.addValueEventListener(new ValueEventListener() { @OverrIDe public voID onDataChange(DataSnapshot dataSnapshot) { for (DataSnapshot snapshot : dataSnapshot.getChildren()) { Adrat adr = snapshot.getValue(Adrat.class); int vr = adr.getVIEwrating(); if(vr < 1) { currentUserUnratedposts.add(adr.getAdID()); } } // do your thing right here } @OverrIDe public voID onCancelled(DatabaseError databaseError) { } }); return currentUserUnratedposts;}
除此之外,我在搜索时发现的另一种方法是Task.await().但是,我不会指望它.
您可以在这里阅读有关此内容的更多信息:
StackOverflow Question
StackOverflow Answer
总结以上是内存溢出为你收集整理的java-无法从从Firebase Realtime数据库检索数据的方法中获取返回值,以在下面的代码行中使用它全部内容,希望文章能够帮你解决java-无法从从Firebase Realtime数据库检索数据的方法中获取返回值,以在下面的代码行中使用它所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)