【问题标题】:Firebase admin sdk listen to realtime databaseFirebase admin sdk 监听实时数据库
【发布时间】:2021-07-01 23:30:31
【问题描述】:

您好,我在 Spring 项目中使用 Firebase 管理 SDK 学习 Firebase 实时数据库。我的主要意图是根据添加到 firebase 数据库主节点的子(新聊天)项目向用户发送通知。

就像上图一样,我的数据库树结构很简单,它在该节点下有一个名为CHATS 的主节点,我在两个用户之间创建了许多其他child node to create 1-to-1 聊天。每个单独的子节点都会有许多其他带有聊天消息的子节点。

使用 Firebase admin sdk 监听主节点,即。 CHATS

  private void startListeningToChats() {
    CountDownLatch latch = new CountDownLatch(1);
    try {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("/" + appProperties.firebaseChatBucketName);
        reference.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                System.out.println("Child Event added" + s + " " + dataSnapshot.getKey() + " " + dataSnapshot.getValue());
                latch.countDown();
            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {
                latch.countDown();
                System.out.println("Child Event changed" + s + " " + dataSnapshot.getKey() + " " + dataSnapshot.getValue());
            }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {
                System.out.println("Child Event removed" + dataSnapshot.getKey());
                latch.countDown();
            }

            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {
                System.out.println("Child Event moved" + s + " " + dataSnapshot.getValue());
                latch.countDown();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                System.out.println("Child Event cancelled" + databaseError.getMessage());
                latch.countDown();
            }
        });
        latch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
        latch.countDown();
    }
}

现在,当子节点发生任何变化时,即在子节点中添加新的聊天消息时,onChildChanged 方法会被触发,并使用包含所有子节点的数据快照。假设如果将新的聊天消息添加到 USER5-USER6 节点,那么 onChildChanged 方法会与所有以前的聊天消息一起触发,但我知道这是预期的行为。将侦听器附加到主节点的原因是要知道两个用户之间何时启动了新的聊天节点。如果我的子节点有多个聊天消息,我担心会花费 firebase 成本,那么每次onChildChanged 方法都会有所有聊天消息的数据快照。

我想知道我们是否可以过滤对子节点所做的更改,以便让onChildChanged 与带有最新添加聊天消息的子节点。

【问题讨论】:

    标签: firebase firebase-realtime-database firebase-admin


    【解决方案1】:

    不久前,当我尝试在 android 中编写聊天应用程序时,我遇到了类似的问题。我很遗憾地告诉你,没有有效的方法来只获取最近的数据。您可以使用 Query 来操作从数据库中获取数据的方式,但它仍然不会那么有效。此外,每次下载所有数据的费用几乎是微不足道的。因此,我会说您查看 Java Admin SDK 的查询功能,如果没有任何帮助,您可以继续检索所有数据并自行过滤。虽然有一种解决方案,但只要您避免使用同一帐户的并发用户,它就很有效。您可以维护同一消息的两个副本,一个节点将包含您在登录时可以使用的所有消息,并且您必须显示所有以前的聊天。当前正在发送的消息将被添加到另一个节点,该消息将由另一个用户检索并添加到第一个节点,并且可以删除来​​自这里的相同消息,以便只留下留下的消息未打开的将保留在此分支上。

    【讨论】:

    • 感谢您分享您的经验,但是您是如何解决的呢?
    • 我使用查询对象对来自 firebase 的消息进行了排序,并使用了一个变量来存储最后一个键的值,每当调用 onChildAdded 方法时,我都会检索我指定的键之后的所有消息存储在变量中。这可以使用 Query 对象下的 startAt() 方法实现。
    • 我没明白你but it is effective as long as you avoid concurrent users using the same account的意思
    • 在并发访问的情况下,用于临时存储消息的第二个节点将被多个源同时访问,不要假设其中一个应用程序比其中一个快几秒钟另一个。速度较快的人会在阅读该消息后立即删除该消息。因此,第二个应用程序不会下载它,因为它已被第一个应用程序删除。我在尝试这种方法时遇到了这个问题,我无法使用相同的凭据限制对数据库的并发访问。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-12
    • 2021-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    相关资源
    最近更新 更多