Firebase android计算子项并将其存储在变量中

时间:2016-12-15 11:51:43

标签: android firebase count firebase-realtime-database

在我的应用程序中,我可以通过datasnapshot.getchildren()来计算子项数。 但是,如果我想将该计数存储在变量中,我该怎么办?

mRefReg.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.i(dataSnapshot.getKey(),dataSnapshot.getChildrenCount()+"Count");

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

包括“mCount = dataSnapshot.getChildren”似乎不起作用。

4 个答案:

答案 0 :(得分:4)

您可能会看到来自Firebase的数据是异步加载的。第一次遇到这种情况时,这是一个很大的范式转变。但是,由于大多数现代云API以这种方式工作,因此最好尽快接受它。

我发现最简单的方法,看看当我们发布一些日志记录时会发生什么:

System.out.println("Before adding listener");
mRefReg.addValueEventListener(new ValueEventListener() {
    public void onDataChange(DataSnapshot dataSnapshot) {
        System.out.println("In onDataChange");
    }
    public void onCancelled(DatabaseError databaseError) { }
});
System.out.println("After adding listener");

与你的直觉告诉你的相反,输出结果将是:

  

添加侦听器之前

     

添加监听器后

     

在onDataChange

原因是(正如我在开始时所说)Firebase异步从数据库中获取数据。了解其原因的有趣方法是更改​​数据(例如在Firebase Database console中)。进行此更改后,将再次调用onDataChange并打印另一个:

  

在onDataChange

不幸的是,这意味着您无法执行以下操作来处理子计数:

int count = -1;
System.out.println("Before adding listener, count="+count);
mRefReg.addValueEventListener(new ValueEventListener() {
    public void onDataChange(DataSnapshot dataSnapshot) {
        count = dataSnapshot.getChildrenCount();
        System.out.println("In onDataChange, count="+count);
    }
    public void onCancelled(DatabaseError databaseError) { }
});
System.out.println("After adding listener, count="+count);

因为输出将是:

  

在添加listener之前:count = -1

     

添加监听器后:count = -1

     

在onDataChange中:count = 3(假设你有3个孩子)

我发现处理此异步加载的最佳技巧是重新构建问题。而不是说"首先我们得到计数,然后我们用它来做xyz",尝试将它框架为"每当我们得到计数时,用它做#xyz"。这意味着您需要将需要计数的代码移动到 onDataChange()中:

mRefReg.addValueEventListener(new ValueEventListener() {
    public void onDataChange(DataSnapshot dataSnapshot) {
        int count = dataSnapshot.getChildrenCount();
        // TODO: show the count in the UI
    }
    public void onCancelled(DatabaseError databaseError) { }
});

如果您这样实现,只要数据库中的项目数发生变化,UI中的计数就会更新。

答案 1 :(得分:2)

您的问题中缺少一些信息,但我想我知道发生了什么。 Firebase中的监听器是异步的,因此您无法轻松设置变量。

要去的选项:

1)在onDataChange方法中声明你的变量。

2)仅在onDataChange方法完成时使用变量。

3)在您声明了监听器的方法中传递回调函数。

答案 2 :(得分:0)

long ct = 0;    

public void Count() {
            databaseReference.child("a").child("b").addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    if (dataSnapshot.exists()) {
                        ct = dataSnapshot.getChildrenCount()`enter code here`;
                    } 
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });

        }

在开头调用此函数,每当firebase数据库中的子计数增加或减少时,它将不断更新变量ct。 希望它有所帮助

答案 3 :(得分:0)

只需执行此操作。函数datasnapshot.getChildrenCount返回long类型值,因此您需要先将其强制转换为整数。

    mRefReg.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                mCount = (int) dataSnapshot.getChildrenCount;
                Log.i(dataSnapshot.getKey(), mCount +""`enter code here`);

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });