Firebase onDataChanged调用很多次(没有更新),有时会调用null值

时间:2017-10-24 12:17:15

标签: java android firebase firebase-realtime-database

我的firebase应用程序中有以下json树

--ashWoYViS3SbHtBhLpvStRleBl13
----items
-------- -KxDDW1FYMUOxea5w5ii
------------- description: "gggh"
------------- name: "gggh"

ashWoYViS3SbHtBhLpvStRleBl13是userId,获得了FirebaseAuth.getInstance()。getUser()。getUid();

-KxDDW1FYMUOxea5w5ii是项目的键,在将项目插入json树之前使用push函数获得。

项目节点下有更多项目,这只是一个样本。

然后我想阅读所有项目,以便在我的应用程序列表中显示它们。我做了以下事情:

ValueEventListener listener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            List<Item> items= utils.convertChildrenToList(dataSnapshot, Item.class);
            getView().setData(customContexts);
            getView().showContent();

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            getView().showError(databaseError.toException(), true);

        }


    };


    Query query = database.getReference("/ashWoYViS3SbHtBhLpvStRleBl13/items")
            .orderByKey();
    query.addValueEventListener(listener);

此时列表中有5个项目,在使用addValueEventListener设置监听器之后,我希望只在onDataChanged中收到一次结果。真正发生的是我每隔几秒就会收到对onDataChanged的无限调用。快照第一次有5个项目。第二次快照为空(null)。第三次快照再次包含5个项目,依此类推,无限循环。

数据库没有更新,因为我不明白为什么我在onDataChanged中变成了多个回调。数据总是在那里,我也不明白为什么快照的值有时为空

如果我使用addListenerForSingleValueEvent,那么我只在回调中收到一个结果&#34; onDataChanged&#34;。有时快照值为null,有时快照具有5个元素。无论如何,它并没有解决我的问题。

我尝试使用Firebase sdk的许多版本,从v11.0.2到firebase 11.4.2,它在所有版本中都会发生。

解决我发现的问题的唯一方法是:

而不是为路径注册侦听器

&#34; / ashWoYViS3SbHtBhLpvStRleBl13 / items&#34;,我为路径注册了一个监听器

&#34; / some_prefix / ashWoYViS3SbHtBhLpvStRleBl13 /项目&#34; (显然,我也使用相同的前缀保存数据)。

然后一切按预期工作,也就是说,我只接收回调中的结果&#34; onDataChanged&#34;。快照不为空,只有在items节点下的数据真正更改时才会收到下一个回调。

或者,如果我使用addListenerForSingleValueEvent,那么我只收到一个回调,其中包含节点&#34; items&#34;中的所有元素。

你能告诉我我在这里做错了什么吗? (因为我不想在用户ID之前使用前缀)。

提前致谢。

1 个答案:

答案 0 :(得分:0)

每次您要进行查询时,都要使获​​取的数据为false,以确保onDatachange读取该方法,但是当onDataChange内的方法要意外调用onDataChange时,由于该获取的数据为true,因此无法访问。 /> 例如,当您在onDataChange中进行插入时,该方法将在其他时间调用它们自己,而无需调用它们。

Boolean fetched = false;

ValueEventListener listener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {

        if (fetched == false) {
            fetched = true;
            List<Item> items = utils.convertChildrenToList(dataSnapshot, Item.class);
            getView().setData(customContexts);
            getView().showContent();
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        getView().showError(databaseError.toException(), true);

    }
};


Query query = database.getReference("/ashWoYViS3SbHtBhLpvStRleBl13/items")
        .orderByKey();

fetched=false;
query.addValueEventListener(listener);