如何由于方法返回DataSnapshot值?
我对爪哇没有太多经验。我不确定这个问题是否很愚蠢,但是我需要从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) {}
});
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这是异步网络API的经典问题。您现在无法返回尚未加载的东西。换句话说,您不能简单地创建一个全局变量,而是在
ondataChange()
方法之外使用它,因为它始终是null
。之所以发生这种情况,是因为ondataChange()
方法称为异步。根据您的连接速度和状态,可能需要从几百毫秒到几秒钟才能获得数据。但是,不仅Firebase实时数据库不同步加载数据,而且几乎所有现代的Web API都可以使用,因为可能需要一些时间。因此,与其等待数据(可以导致用户无反应的应用程序对话框),而是在将数据加载到辅助线程上时继续进行。然后,当数据可用时,请调用您的onDataChange()方法,并且可以使用数据。换句话说,到时
OnDatAchange()
方法被称为您的数据。让我们以一个例子为例,在代码中放置一些日志语句,以更清楚地查看发生了什么。
如果我们运行此代码,则输出将为:
这可能不是您所期望的,而是确切地解释了为什么您的数据在返回时为
null
。大多数开发人员的最初响应是尝试“修复”此
异步行为
,我个人建议反对这一点。网络是异步的,您越早接受您越早学习如何使用现代网络API提高生产力。我发现对这种异步范式的问题最简单。我没有说“先获取数据,然后记录数据”,而是将问题框起来为“开始获取数据。加载数据后,将其记录”。这意味着任何需要数据的代码都必须在
ondataChange()
方法中或从内部调用,因此:如果您想在外部使用它,则有另一种方法。您需要创建自己的回调才能等待Firebase返回数据。为了实现这一目标,首先,您需要创建一个
接口
这样:然后您需要创建一个实际上从数据库中获取数据的方法。此方法应该看起来像这样:
最后,只需调用
readdata()
方法,然后将myCallback
接口的实例作为参数,无论您在任何地方都需要它:是您在
ondataChange()
方法之外使用该值的唯一方法。有关更多信息,您还可以查看此 video 。编辑: 2021年2月26日,
有关更多信息,您可以查看以下文章:
和以下视频:
This is a classic issue with asynchronous web APIs. You cannot return something now that hasn't been loaded yet. In other words, you cannot simply create a global variable and use it outside
onDataChange()
method because it will always benull
. This is happening becauseonDataChange()
method is called asynchronous. Depending on your connection speed and the state, it may take from a few hundred milliseconds to a few seconds before that data is available.But not only Firebase Realtime Database loads data asynchronously, but almost all modern web APIs also do, since it may take some time. So instead of waiting for the data (which can lead to unresponsive application 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. In other words, by the time
onDataChange()
method is called your data is not loaded yet.Let's take an example, by placing a few log statements in the code, to see more clearly what's going on.
If we run this code will, the output will be:
This is probably not what you expected, but it explains precisely why your data is
null
when returning it.The initial response for most developers is to try and "fix" this
asynchronous behavior
, which I personally recommend against this. 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 the data, then log it", I frame the problem as "Start to get data. When the data is loaded, log it". This means that any code that requires the data must be inside
onDataChange()
method or called from inside there, like this:If you want to use that outside, there is another approach. You need to create your own callback to wait for Firebase to return you the data. To achieve this, first, you need to create an
interface
like this:Then you need to create a method that is actually getting the data from the database. This method should look like this:
In the end just simply call
readData()
method and pass an instance of theMyCallback
interface as an argument wherever you need it like this:This is the only way in which you can use that value outside
onDataChange()
method. For more information, you can take also a look at this video.Edit: Feb 26th, 2021
For more info, you can check the following article:
And the following video:
从
众所周知,Firebase API是异步的。因此,我们需要为此创建一个回调。首先,让我们创建一个界面:
一个方法作为参数作为一个tye firebasecallback的对象:
现在,要读取数据,您只需将上述方法调用作为参数作为一个类型的firebasecallback的对象:
有关更多信息,有关更多信息,更多信息,您可以查看以下文章:
“ noreferrer”>如何使用get()?和以下视频
Starting from the "19.6.0" version, the Firebase Realtime Database SDK contains a new method called get(), that can be called either on a DatabaseReference or a Query object:
As we already know, Firebase API is asynchronous. So we need to create a callback for that. First, let's create an interface:
And a method that takes as an argument an object of tye FirebaseCallback:
Now, to read the data, you need to simply call the above method passing as an argument an object of type FirebaseCallback:
For more info, you can check the following article:
And the following video:
我相信我明白你在问什么。尽管您说您想从获取方法中“返回”它(本身),但实际上您只想在获取完成后可以使用检索的值。如果是这样,这就是您需要做的:
一旦获取成功,就可以检索到的值,您可以做到。许多变量的东西。 4a和4b是一些简单的示例:
4A。 编辑:
作为使用的示例,您可以触发使用
yournamevariable
的其他所有需要运行的其他内容(并且您可以确定它yournamevariable
null)4B。 编辑:
作为使用的示例,您可以在按钮的OnClickListener触发的函数中使用变量。
尝试一下。
然后,您可以在整个课程中想要的任何地方使用
。
注意:只需确保您检查
您的namevariaible
在使用它时不是null,因为ondataChange
是异步的,并且在您尝试在其他地方使用它时可能尚未完成。I believe I understand what you are asking. Although you say you want to "return" it (per se) from the fetch method, it may suffice to say you actually just want to be able to use the value retrieved after your fetch has completed. If so, this is what you need to do:
Once your fetch succeeds, you could do many things with the variable. 4a and 4b are some simple examples:
4a. Edit:
As an example of use, you can trigger whatever else you need to run in your class that uses
yourNameVariable
(and you can be sure ityourNameVariable
not null)4b. Edit:
As an example of use, you can use the variable in a function that is triggered by a button's onClickListener.
Try this.
Then, you can use
yourNameVariable
wherever you would like throughout your class.Note: just be sure you check that
yourNameVariable
is not null when using it sinceonDataChange
is asynchronous and may not have completed at the time you attempt to use it elsewhere.这是一个疯狂的主意,在OnDataChange内部,将其放入文本视图中,可见度消失了
textview.setvisiblity(gone)
或其他然后执行类似的操作
,然后使用
textView.getText()。toString()
只是一个疯狂的简单想法。
Here's a crazy Idea, inside onDataChange, put it inside a TextView with visibility gone
textview.setVisiblity(Gone)
or something,then do something like
then later get it with
textview.getText().toString()
just a crazy simple Idea.
使用
livedata
作为返回类型,并观察其值的更改以执行所需的操作。然后,从您的
活动/片段
观察livedata
和内部on Changed
执行您所需的操作。Use
LiveData
as return type and observe the changes of it's value to execute desired operation.Then from your
Activity/Fragment
observe theLiveData
and insideonChanged
do your desired operation.这不是解决方案,只是一种访问代码组织方法之外数据的方法。
另一种实现结果的方法(但不一定是解决方案)
声明公共变量
在异步方法
中设置此变量,如果异步调用不长,则在第二种方法中使用变量,
它几乎一直工作。
This is NOT a solution, just a way to access the data outside the method for code organization.
Another way of achieving result (but not necessarily a solution)
Declare a public variable
Set This Variable Inside The Async Method
Use The Variable Anywhere
In the second method if the async call is not long it will nearly work all the time.