我想要返回一个包含其中一些内容的对象。
这是宣言;
Object user_det = get_user_det();
这是功能代码:
private Object get_user_det() {
Firebase f_user = new Firebase("https://myapp.firebaseio.com/User/");
f_user.addListenerForSingleValueEvent(new ValueEventListener(){
@Override
public void onDataChange(DataSnapshot snap_user) {
// TODO Auto-generated method stub
Iterable<DataSnapshot> rs = snap_user.getChildren();
Iterator<DataSnapshot> irs = rs.iterator();
long allNum2 = snap_user.getChildrenCount();
int maxNum2 = (int)allNum2;
int count_user = 1;
while(irs.hasNext())
{
if(count_user <= maxNum2)
{
Firebase user_data = new Firebase("https://myapp.firebaseio.com/");
AuthData authData = user_data.getAuth();
Map<String, Object> nPost = (Map<String, Object>) irs.next().getValue();
String db_email = nPost.get("email_addr").toString();
if (authData != null) {
String usr_email = authData.getProviderData().get("email").toString();
if(usr_email.equals(db_email))
{
//NB: I WANT TO ADD THE FOLLOWING INTO THE OBJECT
String disp_name = nPost.get("disp_name").toString();
String real_name = nPost.get("real_name").toString();
}
} else {
System.out.println("Failed");
}
}
count_user++;
}
}
@Override
public void onCancelled(FirebaseError arg0) {
// TODO Auto-generated method stub
}
});
return null; //NB: I NEED TO RETURN THE OBJECT HERE.
}
我想返回字符串disp_name和real_name,但它们在addListenerForSingleValueEvent中,所以如何将它们取出并将其返回给函数。
我写了#34; NB&#34;在我需要帮助的代码中。
感谢您的时间。
答案 0 :(得分:1)
如果要从java中的方法返回一个对象,请执行以下操作:
Object类: 它包含Object的结构,并定义其中的数据。还包括轻松获取数据的方法。
private class myObject {
private String name;
private String realName;
//The constructor, so you can set the data when creating the Object.
public myObject (String disp_name, String real_name) {
name = disp_name;
realName = real_name;
}
//Getter methods, to get the data.
public String getRealName() {return realName;}
public String getDisplayName() {return name;}
}
您的代码:
private Object get_user_det() {
myObject o; //Declare it, so it can be returned.
...
String disp_name = nPost.get("disp_name").toString();
String real_name = nPost.get("real_name").toString();
o = new myObject(disp_name, real_name); //create it and set the data.
...
return myobject; //return the new Object with the data.
}
从对象获取数据:
myObject o = get_user_det(); //Call the metod which return our Object.
String realName = o.getRealName(); //Get the data from the Object.
String displayName = o.getDisplayName;
在您的情况下,使用String数组会更容易。
希望这有帮助。
答案 1 :(得分:1)
如果您在代码中添加一些println
,可能最容易看到正在发生的事情:
private Object get_user_det() {
Firebase f_user = new Firebase("https://myapp.firebaseio.com/User/");
System.out.println("Adding listener");
f_user.addListenerForSingleValueEvent(new ValueEventListener(){
@Override
public void onDataChange(DataSnapshot snap_user) {
System.out.println("Data received");
}
@Override
public void onCancelled(FirebaseError arg0) {
// TODO Auto-generated method stub
}
});
System.out.println("Returning");
return null; //NB: I NEED TO RETURN THE OBJECT HERE.
}
如果您执行此代码,您将看到它记录:
Adding listener
Returning
Data received
最有可能的是,这不是您的预期。但希望如果您阅读下面的解释是有道理的。
当您注册听众时:
f_user.addListenerForSingleValueEvent(new ValueEventListener(){
您告诉Firebase 开始监听活动。它关闭并开始从服务器检索数据。
由于检索数据可能需要一些时间,因此它会异步执行此检索,以便您的线程不会被阻止。完全检索数据后,Firebase会在您的侦听器中调用onDataChange
方法。
在您开始收听和调用时间onDataChange
之间,您的代码将继续执行。因此,无法返回异步加载的数据,因为在函数返回时,数据尚未加载。
免责声明:我不是Java中解决此问题的专家,因此我的解决方案可能存在问题。如果^ H ^如果您发现任何问题,请在评论中报告。
我知道这个问题有三种可能的解决方案:
get_user_det
并在数据可用后调用该函数您可能会想要选择选项1,因为它与您加载数据的心理模式最匹配。虽然这不一定是错误的,但请记住,有一个很好的理由是异步完成加载。可能值得学习如何处理异步性问题&#34;惩罚现在。
我没有为所有解决方案编写示例,而是提及一些相关问题:
答案 2 :(得分:1)
Firebase使用反射来构建JSON树对象以保存到数据库。检索此JSON树时,可以将其强制转换回原始对象。就像序列化和反序列化一样。这意味着您在尝试重建&#34;时不需要处理键和值。你的对象就像你一样。这一切都可以这样完成:
YourObject object =(YourObject)dataSnapshot.getValue(YourObject.class);
请注意YourObject.class
中的getValue()
。这告诉firebase通过此类反映并使用dataSnapshot查找适当的访问器。
确保您的对象有:
@JsonIgnore
注释)您的对象应该是什么样的:
public class YourObject {
private String displayName;
private String realName;
public YourObject() { /*Empty constructor needed for Firebase */ }
// Accessors
public void setRealName(String realName){
this.realName = realName;
}
public String getRealName(){
return this.realName;
}
public String getDisplayName(){
return this.displayName;
}
public void setDisplayName(String displayName){
this.displayName = displayName;
}
}
然后,在任何firebase回调中,您只需将DataSnapshot转换为对象:
public void onDataChange(DataSnapshot snap_user) {
YourObject object = new Object;
if(snap_user.getValue() != null) {
try {
object = (YourObject) snap_user.getValue(YourObject.class); <-- Improtant!!!
} catch(ClassCastException ex) {
ex.printStackTrace();
}
}
return object;
}
您似乎正在检索许多对象。执行此操作时,我发现最好使用onChildEventListener
然后对该节点中YourObject
的每个进行调用,onChildAdded(DataSnapshot ds, String previousChild);
将被调用。