【问题标题】:Why is Firebase onChildAdded not being called?为什么不调用 Firebase onChildAdded?
【发布时间】:2017-12-18 13:55:40
【问题描述】:

我想在我的 firebase 数据库中的“服装”参考下获取所有 firebase 节点。为此,我将ChildEventListener 附加到引用,并在onChildAdded 回调中,我将Clothing 对象添加到服装对象列表中,假设onChildAdded 回调被调用的次数是下面有节点的次数“服装”参考。

mClothingRef = FirebaseDatabase.getInstance()
                               .getReference()
                               .child("clothing");
final List<Clothing> clothingItems = new ArrayList<>();

mClothingRef.addChildEventListener(new ChildEventListener() {
    public void onChildAdded(DataSnapshot snapshot, String s) {
        Clothing clothing = snapshot.getValue(Clothing.class);
        clothingItems.add(clothing);
        Log.d(TAG, "onChildAdded called");      
    }
    public void onCancelled(DatabaseError databaseError) {
        Log.e(TAG, databaseError.getMessage() + " " + 
        databaseError.getCode() + " " + databaseError.getDetails()  + " " + databaseError.toString());
        mEventBus.post(new ListClothingFailEvent());
    }
    ...
}

这是数据库结构:

-->root
---->clothing
------>clothing_id
-------->title
-------->category
-------->img_download_url
------>clothing_id_1
-------->title
-------->...

我需要获取服装节点下的所有节点。

我的数据库安全规则目前是:

{
  "rules": {
    ".read": "auth == null",
    ".write": "auth != null"
  }
}

当调用包含此代码的方法时,onChildAdded 回调不是,而是onCancelled 回调带有权限被拒绝的数据库错误。为什么会这样?

【问题讨论】:

  • 当我在该行上添加一个断点时,它将被忽略,因为该行从未被调用。根据调试器,服装节点的参考 url 是:good-deal-9a0b2.firebaseio.com/clothing,这似乎是正确的
  • @TomFinet 你能分享你完整的活动代码吗?
  • 此代码不在活动中,但使用mCatalogRepository.loadClothing() 从活动中调用。我会把它添加到问题中。

标签: android firebase firebase-realtime-database


【解决方案1】:

要显示该数据,请使用以下代码:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference clothingRef = rootRef.child("clothing");
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        List<Clothing> clothingItems = new ArrayList<>();
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            Clothing clothing = snapshot.getValue(Clothing.class);
            clothingItems.add(clothing);
        }
        Log.d("TAG", clothingItems);
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
clothingRef.addListenerForSingleValueEvent(eventListener);

【讨论】:

  • 记得在onDataChange()方法中声明并使用ArrayList,否则会是null
  • 问题似乎是我的方法和您的方法都拒绝了数据库错误权限@Alex Mamo
  • 您是否在 Firebase 控制台中将用于测试的权限更改为 true
  • 现在我有了,它可以工作了。但是我现在有另一个问题。在我的问题中,我将clothingItems 定义为最终的,因此无法更改。但是,每次调用 onChildAdded 回调时,我都需要添加每个服装项目。我该如何解决这个问题?
【解决方案2】:

每当在任何节点中添加/删除/修改更改时,我们都应该使用 onChildChanged 回调方法而不是添加。在这个方法中,我们得到了 DataSnapshot 的实例,它具有新的所需数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    相关资源
    最近更新 更多