我对java没有太多经验。我不确定这个问题是否愚蠢,但我需要从firebase实时数据库中获取用户名,并将此名称作为此方法的结果返回。所以,我知道如何得到这个值,但我不知道如何返回它作为这个方法的结果。最好的办法是什么?
private String getUserName(String uid) {
databaseReference.child(String.format("users/%s/name", uid))
.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
// How to return this value?
dataSnapshot.getValue(String.class);
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
}
5条答案
按热度按时间t8e9dugd1#
这里有一个疯狂的想法,在ondatachange中,把它放到一个没有可见性的文本视图中
textview.setVisiblity(Gone)
或者做些什么,然后像然后再拿回来
textview.getText().toString()
只是一个疯狂的简单想法。sczxawaw2#
这是异步webapi的一个典型问题。您现在不能返回尚未加载的内容。换句话说,您不能简单地创建一个全局变量并在外部使用它
onDataChange()
方法,因为它总是null
. 这是因为onDataChange()
方法称为异步。根据您的连接速度和状态,可能需要几百毫秒到几秒钟才能获得数据。但是,不仅firebase实时数据库异步加载数据,而且几乎所有现代webapi都是这样,因为这可能需要一些时间。因此,不必等待数据(这可能导致用户的应用程序对话框没有响应),而是在将数据加载到辅助线程时继续执行主应用程序代码。当数据可用时,将调用ondatachange()方法,并可以使用数据。换句话说,到那时
onDataChange()
方法调用时,数据尚未加载。让我们举一个例子,通过在代码中放置一些日志语句,来更清楚地看到发生了什么。
如果我们运行此代码,输出将是:
在连接侦听器之前!
连接侦听器之后!
ondatachange()方法内部!
这可能不是您所期望的,但它确切地解释了为什么您的数据
null
归还的时候。对于大多数开发人员来说,最初的React是尝试“修复”这个问题
asynchronous behavior
我个人建议不要这样做。web是异步的,您越早接受这一点,就越早学会如何使用现代web API提高效率。我发现为这个异步范例重新构造问题是最容易的。我没有说“首先获取数据,然后记录”,而是将问题定义为“开始获取数据”。加载数据时,记录它”。这意味着任何需要数据的代码都必须在
onDataChange()
方法或从内部调用,如下所示:如果你想在外面使用,还有另一种方法。您需要创建自己的回调来等待firebase返回数据。要实现这一点,首先,您需要创建
interface
这样地:然后您需要创建一个从数据库中实际获取数据的方法。此方法应如下所示:
最后只要打个电话就行了
readData()
方法并传递MyCallback
接口作为参数,在需要时如下所示:这是您可以在外部使用该值的唯一方法
onDataChange()
方法。更多信息,你也可以看看这个视频。r6vfmomb3#
这不是解决方案,只是访问代码组织方法之外的数据的一种方法。
实现结果的另一种方式(但不一定是解决方案)
声明公共变量
在异步方法中设置此变量
在任何地方使用变量
在第二种方法中,如果异步调用不长,那么它几乎可以一直工作。
fwzugrvs4#
我相信我理解你的要求。尽管您说您想从fetch方法“返回”它(本身),但您实际上只想在fetch完成后使用检索到的值就足够了。如果是这样,您需要做的是:
在类的顶部创建一个变量
找回你的价值(你做得基本正确)
将类中的公共变量设置为检索到的值
一旦获取成功,就可以使用变量执行许多操作。4a和4b是一些简单的例子:
4a级。edit:作为一个使用示例,您可以触发在使用
yourNameVariable
)你可以肯定yourNameVariable
(不为空)第4b条。编辑:作为一个使用示例,您可以在由按钮的onclicklistener触发的函数中使用变量。
试试这个。
然后,你可以使用
yourNameVariable
无论你想在课堂上什么地方。注意:一定要检查一下
yourNameVariable
使用时不为null,因为onDataChange
是异步的,在尝试在其他地方使用时可能尚未完成。gtlvzcf85#
使用
LiveData
作为返回类型并观察其值的变化以执行所需的操作。然后从你的
Activity/Fragment
观察LiveData
还有里面onChanged
做你想要的手术。