0
votes

Hi i was learning Firebase realtime database in my spring project using Firebase admin SDK. My main intension is to send the notification to users based on child(new chat) items added to the main node of firebase database. enter image description here

Just like in above image my database tree structure is simple and it has main node called CHATS under this node am creating many other child node to create 1-to-1 chat between two users. Evey single child node will have many other child nodes with chat messages.

Using Firebase admin sdk am listening to main node ie. 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();
    }
}

Now when ever any changes happens to child nodes, i.e when new new chat message is added inside child node, onChildChanged method is fired with datasnapshot having all the child nodes. Suppose if new chat message is added to USER5-USER6 node then onChildChanged method is fired with all previous chat messages but i know this is expected behaviour. And the reason am attaching listener to main node is to know when new chat node is initiated between two users. Am afraid of firebase costing if my child node has multiple chat messages then everytime onChildChanged method will have datasnapshot with all chat messages.

I wanted to know if we can filter the changes the done to child node so that to have onChildChanged with child node with lastest added chat message.

1

1 Answers

0
votes

I went through similar problems a while ago when I tried to write a chat app in android. I'm sad to tell you that there is no effective way to only take the recent data. You can use Query to manipulate the way you fetch data from the database, it still wouldn't be that effective. Also the expense in downloading all the data every time is almost insignificant. So, I'd say you look into the Query functions for Java Admin SDK and if it isn't of any help, you can proceed with retrieving all data and filtering it yourself. There is one solution though, but it is effective as long as you avoid concurrent users using the same account. You can maintain two copies of the same message, one node will contain all messages which you can use whenever you login and you have to display all the previous chats. The messages that is currently being sent will be added to another node, this messages will be retrieved by the other user and will be added to the first node, and the same message from here can be deleted, so that only the messages that was left unopened will remain on this branch.