【问题标题】:ArrayList won't store Firebase database listArrayList 不会存储 Firebase 数据库列表
【发布时间】:2018-09-20 07:16:10
【问题描述】:

我想将我的数据库子项存储在我的模型的数组列表中。

型号:

public class testInformation {
private String taskName;
private String answer;

public testInformation() {
}

public String getTaskName() {
    return taskName;
}

public void setTaskName(String taskName) {
    this.taskName = taskName;
}

public String getAnswer() {
    return answer;
}

public void setAnswer(String answer) {
    this.answer = answer;
}
}

在片段的onCreate()方法中,我调用了一个GetDataFromDatabase()方法,如下所示:

public void GetDataFromDatabase(){
    mFirebaseDatabase= FirebaseDatabase.getInstance();
    myref=mFirebaseDatabase.getReference().child("solutionKey");
    myref.keepSynced(true);
    myref.addListenerForSingleValueEvent(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot ds:dataSnapshot.getChildren()){
                testInformation testInformation=new testInformation();
                testInformation.setTaskName(ds.getKey().toString());
                testInformation.setAnswer(ds.getValue().toString());
                results.add(testInformation);
            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
}

我有一个名为results 的公共ArrayList<testInformation> 变量,用于存储数据库中的数据,但即使在调用GetDataFromDatabase() 之后,results 列表似乎是空的,但是当我在OnDataChange() 方法处设置断点,它似乎被正确的数据填满了。

我的问题是,如何从OnDataChange() 中获取已填满的results 列表以使用它?

编辑:这个列表不会被修改或改变,所以我只需要得到它一次,这就是我使用addListenerForSingleValueEvent()方法的原因。

【问题讨论】:

  • 很可能,您正在从 ArrayList 中读取数据,然后再填充数据。如果您将代码发布到您从列表中读取的位置,我可以尝试提供帮助。
  • 您将结果用于什么目的?
  • 这是一个 testInformation 对象列表,其中包含从 Firebase 数据库中提取的数据。
  • 你在哪里使用列表?可能的问题是您希望在 GetDataFromDatabase 函数返回时填充结果列表,这不一定是真的。事件监听器被异步调用。如果您能发布更多代码,我可以提供帮助。

标签: android firebase arraylist firebase-realtime-database


【解决方案1】:

这就是代码的结构:

public class EndOfTestFragment extends Fragment {


    private FirebaseDatabase mFirebaseDatabase;
    private DatabaseReference myref;
public ArrayList<testInformation> results;

...

@Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
...
GetDataFromDatabase();
...
}
public void GetDataFromDatabase(){
        mFirebaseDatabase= FirebaseDatabase.getInstance();
        myref=mFirebaseDatabase.getReference().child("solutionKey");
        myref.keepSynced(true);
        myref.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot ds:dataSnapshot.getChildren()){
                    testInformation testInformation=new testInformation();
                    testInformation.setTaskName(ds.getKey().toString());
                    testInformation.setAnswer(ds.getValue().toString());
                    results.add(testInformation);
                }
            }
            @Override
            public void onCancelled(DatabaseError databaseError) {
            }
        });
    }

【讨论】:

  • 你想对数据做什么?显示它?
  • 这是一个智商测试,我想将存储在 Firebase 数据库中的解决方案密钥提供给评估类,以处理用户的正确答案。
【解决方案2】:
public class EndOfTestFragment extends Fragment {
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference myref;
public ArrayList<testInformation> results;

//...

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    //...
    GetDataFromDatabase();// This returns before results.add(...) is called
    // Whatever code is after this line gets run before results list has data
    /* LABEL#1 */
    // The results list is probably NOT populated yet so don't use it here
}
public void GetDataFromDatabase() {
    mFirebaseDatabase= FirebaseDatabase.getInstance();
    myref=mFirebaseDatabase.getReference().child("solutionKey");
    myref.keepSynced(true);

    myref.addListenerForSingleValueEvent(new ValueEventListener() {// This function returns immediately, does not wait for data from Firebase...
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            /* LABEL#2 */
            for (DataSnapshot ds:dataSnapshot.getChildren()){
                testInformation testInformation=new testInformation();
                testInformation.setTaskName(ds.getKey().toString());
                testInformation.setAnswer(ds.getValue().toString());
                results.add(testInformation);
            }
            // The results list is populated now, do whatever you want with it here
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
}

LABEL#1中的代码 LABEL#2

之前执行

只要数据可用,就会在后台调用onDataChange(...) 函数。
addListenerForSingleValueEvent() 不等待数据,立即返回。

【讨论】:

  • 我有点想通了。该活动有 3 个片段,最后调用 EndOfTestFragment。当我在调试模式下运行并在 onDataChange() 处放置一个断点时,它会在第二个片段的开头中断并处理该方法。如果我在活动中创建一个 ArrayList,并在 OnDataChange() 中填充该 ArrayList,我能否在 EndOfTestFragment 片段中使用该列表?
  • 第二个片段中有 onDataChange() 吗?
  • 第三个。我通过将整个 GetDataFromDatabase() 数据删除到活动的 onCreate() 并将值添加到静态 ArrayList() 来解决这个问题,然后从第三个片段访问它来处理它,但问题是在我之前将片段调用到活动中,评估方法运行。它应该得到两个数组列表,但此时第二个是空的。
  • 您必须发布您正在谈论的代码,以便我可以进一步提供帮助。在没有代码的情况下,我现在可以告诉你的是,你想对 ArrayList 做的任何事情都应该发生在 onDataChange() 方法中。
猜你喜欢
  • 2021-10-12
  • 1970-01-01
  • 2020-04-08
  • 1970-01-01
  • 1970-01-01
  • 2016-11-15
  • 2018-09-13
  • 1970-01-01
  • 2017-05-26
相关资源
最近更新 更多