IndexOn计算我数据库中的总用户

时间:2018-08-31 12:51:44

标签: java android firebase firebase-realtime-database

我有一个大约有7-8k用户的数据库,每当我执行getChildrenCount()来计算我的应用程序中有多少人时,我确实要等待很多时间才能处理并启动它。

我想知道是否存在例如在我的数据库中存储长变量的方法,例如

totalusers = 7561

可以在每次将新用户添加到根节点时进行更新,所以我只查询该totalusers并在每次确切数量的用户时快速获取

我在考虑这样的事情来跟踪我的用户,只是查询1个变量并尽快获取数据

"rules": {
    "users": {
        ".indexOn": "totalusers"

    }

这是实现此行为的好方法吗?

编辑:

这就是我现在正在做的

  public long getUsers(DatabaseReference mDatabase){

        mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if(dataSnapshot.exists()){
                    users = dataSnapshot.getChildrenCount();
                    Log.e(TAG, "onDataChange: "+users);
                }


            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });

        return users;
    }

但是这太慢了,就像1分钟之内无法计数7500个用户一样,我的其他firebase操作直到此操作完成后才执行,因此它阻止了我的UI且不显示任何内容

谢谢!

2 个答案:

答案 0 :(得分:3)

Firebase数据库(实时数据库和Firestore数据库)都是NOSQL数据库,诸如count之类的东西在它们上的表现并不理想。

由于您正在使用Firebase身份验证,因此可以使用Firebase功能来实现您的目标。您可以编写函数,这些函数将在Firebase项目中的每一次发生时都运行。 creation of an user是这些“事物”之一。简而言之,您可以在每次创建新用户时执行逻辑,并通过该逻辑更新用户数。这是一个示例:

exports.updateUserCount = functions.auth.user().onCreate((user) => {
  // here goes your logic. You'll update the count here
});

因此,您可以通过这种方式将计数存储在实时数据库或Firestore中。由您决定将价值放在何处。另外,您可以对用户删除执行相同的操作,但是使用onDelete()方法注册一个函数。

这将非常快,并且您将获得一个不必每次都需要确定的值。请参考下面的链接以获取有关Firebase功能的完整参考

https://firebase.google.com/docs/functions/

答案 1 :(得分:1)

您已经发现,Firebase(像许多NoSQL数据库一样)没有内置的聚合操作。因此,现在要计算数据库中的用户节点数量,需要下载所有用户节点,然后在应用程序中对其进行计数:如果只需要计数,那么带宽就非常浪费。

一种常见的方法是将计数作为单独的值存储在数据库中,然后在每次对users节点进行更新时更新该计数器。您可以从客户端代码执行此操作,但如今,您可能还需要考虑从Cloud Functions for Firebase执行此操作。实际上,这种用例非常普遍,它是Github上functions-samples回购中的示例之一:https://github.com/firebase/functions-samples/tree/master/child-count

顺便说一句:格雷戈里奥的答案也是完全正确的。我只是想展示一种更接近您当前方法的替代方法。