java - 仅从 Firebase 的联系人列表中检索数据

标签 java android firebase firebase-realtime-database

我正在开发一个 Android 应用程序,我想在其中检索用户的帖子,这些用户的联系电话按 timestamp 的降序保存在手机中。

现在我正在检索所有用户列表。如果手机中存在联系电话,则显示用户的帖子。因为我想按时间戳的降序排序,所以我必须先检索所有联系人的帖子,然后再对它们进行排序。

Users: { 
            7828272892 : {
                 name: xyz, 
                 gender: male,
                 phoneNo: 7828272892
                 PostsForThisUser: {
                     SomeKey1: {
                         content: "This is post 1", timestamp: "123"} 
                     SomeKey2: {
                         content: "This is post 2", timestamp: "124"}   

                }},

            7924272894 : {
                name: abc,
                gender: male,
                phoneNo: 7924272894
                PostsForThisUser: {
                         SomeKey3: {
                             content: "This is post 1", timestamp: "234"} }},
            }

我能想到的一个更好的解决方案是,为帖子制作单独的表格并通过帖子的关键进行跟踪。但是,在这里我也必须先获取所有帖子并按时间戳对它们进行排序。有没有更好的解决办法?

哪个更好?

  1. 检索所有用户,然后查看联系人列表。
  2. 为手机中的每个联系电话打开监听器。

最佳答案

首先,即使您的模式可以帮助您实现您想要的,我可以说这不是一个非常可行的模式,因为您要在每个用户对象下添加它的所有帖子。这意味着每次您尝试获取特定用户的一些详细信息(比如 name)时,您都在下载整个用户对象,包括他的所有帖子,我可以说这是一种浪费带宽资源。试着想一想如果您需要显示数据库中所有用户名的列表会发生什么。所以在用户名旁边,您将下载所有用户的所有帖子。这是一种不好的做法。

请记住,构建 Firebase 数据库没有完美的解决方案。最好的解决方案是满足您的需求并使您的工作更轻松的解决方案。记住一切都是为了 View ,在我看来你可以有一个模式,你应该在其中创建一个名为 posts 的新顶级集合,并在每个用户电话号码下添加其个人帖子。架构应如下所示:

 Firebase-root
    |
    --- users
    |    |
    |    --- userPhoneNo
    |          |
    |          --- name: "xyz,"
    |          |
    |          --- gender: "male"
    |          |
    |          --- phoneNo: "7828272892"
    |
    --- posts
         |
         userPhoneNo
            |
            --- postIdOne
            |     |
            |     --- content: "This is post 1"
            |     |
            |     --- timestamp: 123
            |
            --- postIdTwo
                  |
                  --- content: "This is post 2"
                  |
                  --- timestamp: 124

因此,为了获取特定用户的所有帖子,无需下载任何其他内容。要获取使用模型类排序的特定用户的所有帖子,请使用以下代码:

String phoneNo = FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("posts").child(phoneNo).orderByChild("timestamp");
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            PostClass postClass = ds.getValue(PostClass.class);
            Log.d("TAG", postClass.getContent());
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {}
};
query.addListenerForSingleValueEvent(valueEventListener);

如果你愿意,甚至更简单,使用 String 类:

String phoneNo = FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("posts").child(phoneNo).orderByChild("timestamp");
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String content = ds.child("content").getValue(String.class);
            Log.d("TAG", content);
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {}
};
query.addListenerForSingleValueEvent(valueEventListener);

在这两种情况下,您的 logcat 中的输出将是:

This is post 1
This is post 2

或者如果您使用相反的顺序:

This is post 2
This is post 1

编辑:根据聊天中的评论,OP 要求解决听起来像这样的问题:

“让我重申一下我的问题。在我的系统中,假设有 10,000 个用户。但是用户将只能看到他有联系电话的用户的帖子。这就像 WhatsApp 故事功能。”

响应:在这种情况下,您应该在每个用户下创建一个映射,您需要在其中存储用户拥有的用户联系电话号码。但在这种情况下,您应该查询您的数据库两次。首先获取他拥有的用户的联系号码,其次,根据这些号码实际获取这些用户的帖子。

关于java - 仅从 Firebase 的联系人列表中检索数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51659674/

相关文章:

java - 使用部分显式命令然后另一个命令?

java - 程序未读取第一个字符串输入

Firebase函数获取用户电话号码

ios - Array.map() 产生 '[T]' ,而不是预期的上下文结果类型 '[String: Any?]'

java - SAP BO CMC - CMC 上的 Information Steward 链接错误(SBOP BI 4.1 sp5 和 SBO EIM 4.2 sp3): Servlet execution threw an exception

java.lang.NoSuchMethodError : javax. servlet.ServletContext.getContextPath()Ljava/lang/String;

javascript - React Native,将身份验证 token 传递给索引

android - 使用 Ion 环绕 ImageView

android - 需要帮助 Kotlin Coroutines、Architecture Component 和 Retrofit

javascript - 有没有一种简单的方法可以在 web worker 中运行 Firebase?