2

I am trying to delete old messages into a FriendlyChat using timestamp. I am using this post How to delete firebase data after "n" days to try to solve. The problem i have: This code to my firebase database is deleting all messages not only the messages I need.

My firebase database JSON:

{
  "messages" : {
    "Bl0AiMMUXsV2H58lqoj0rO84" : {
      "-KYo1YqO9vQ4Fcc07TcU" : {
        "dateCreatedGu" : {
          "date" : 1481563061846
        },
        "name" : "nameOfUser",
        "photoUrl" : "https://lh6.g/photo.jpg",
        "text" : "h"
      },
      "-KYo1atRyY3VYxuTZRPZ" : {
        "dateCreatedGu" : {
          "date" : 1481563074335
        },
        "name" : "\"nameOfUser\"\"",
        "photoUrl" : "https://lh6.googleusercontent.com.../-photo.jpg",
        "text" : "g"
      },
      "-KYo1bQXtJNB94et25m2" : {
        "dateCreatedGu" : {
          "date" : 1481563076516
        },
        "name" : "Gus",
        "photoUrl" : "https://lh6.../photo.jpg",
        "text" : "b"
      },
      "-KYo4GmLdM0TyT_Aym0u" : {
        "dateCreatedGu" : {
          "date" : 1481563774514
        },
        "name" : "gus",
        "photoUrl" : "https://lh6.go.../photo.jpg",
        "text" : "h"
      }
    }
  }
}

My snippet code Android :

mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference("messages");


//beginn n-days
long cutoff = new Date().getTime() - TimeUnit.MILLISECONDS.convert(30, TimeUnit.DAYS);

Query oldItems = mFirebaseDatabaseReference.orderByChild("timestamp").endAt(cutoff);
//

oldItems.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot snapshot) {
        for (DataSnapshot itemSnapshot: snapshot.getChildren()) {
            itemSnapshot.getRef().removeValue();
        }
    }

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

//end n-days

The difference here is my timestamp into date is into "dateCreatedGu and not on the message directly because I used Map to store the timestamp .

What is wrong? How can I correctly delete only the messages I need - the messages older than 30 days for example? I tried to change the period form 30 days to 30 seconds into cutoff = new Date().getTime() - TimeUnit.MILLISECONDS.convert(30, TimeUnit.SECONDS);to verify the code.

I tried to change from addValueEventListener to add ChildEventListener...

i understood that orderByValue is used when you are not reading an object with attributes but reading directly the attribute. I understood that in this case it is better to optimize the code using orderbyKey because the key are stored in the alphabetical order during time - jumping values) - usefull to optimeze the search of timestamp that increasing too. I understood that addChildEventListener tries to read each value inside your database f exist more than one message (for example). But i still not found how to delete only the messages I need. How can i do it with my database?

Community
  • 1
  • 1
Gustavomcls
  • 1,655
  • 2
  • 12
  • 20

2 Answers2

1

Since you nested the timestamp, you need to order by that nested property in your query:

Query oldItems = mFirebaseDatabaseReference.orderByChild("dateCreatedGu/date").endAt(cutoff);
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Also, I don't see `timestamp` in the JSON. I suspect Gustavomcis intended to use `date`. – Bob Snyder Dec 12 '16 at 18:52
  • Good catch. I was running out as I was typing the code. I fixed it. – Frank van Puffelen Dec 12 '16 at 19:30
  • The code with Query oldItems = mFirebaseDatabaseReference.orderByChild("dateCreatedGu/date").endAt(cutoff) is still deleting all messages. I used (30, TimeUnit.DAYS); and still deleting messages from seconds ago, and began to delete all new messages too. I renamed the name of the button that started the process to delete the messages. Because now, without push the button to delete messages, now all messages began to be deleted instantly. Is there a signal from this button not caught starting the process? Messages are still be deleted. – Gustavomcls Dec 12 '16 at 20:25
  • It sounds like you have another process that is deleting the messages. – Frank van Puffelen Dec 12 '16 at 23:26
  • The snapshot.getRef() is giving: = nameOfApp.firebaseio.com/messages - I changed the word nameOfApp here. The App stopped to kill messages from possible about another process but is still deleting all messages from the address is given by: snapshot.getRef() Instead deleting only the messages specified in the query. – Gustavomcls – Gustavomcls Dec 13 '16 at 15:12
0

The soluton to do not delete all the node is: From

mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference("messages");

Change to

mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference("messages/Bl0AiMMUXsV2H58lqoj0rO84");

or do this

Query oldItems = mFirebaseDatabaseReference.child("Bl0AiMMUXsV2H58lqoj0rO84").orderByChild("dateCreatedGu/date").endAt(cutoff);

because the code itemSnapshot.getRef() is returning the parent node of all your messages which is "Bl0AiMMUXsV2H58lqoj0rO84" that's why when you do the removeValue() method, all of your messages will be deleted. Your database reference should be at the id (I assume this is a uid) under your messages node.

the Firebase team helped me to solve this.

To use this code, it is necessary to call first another function that discover the name of the node, in this case the node:Bl0AiMMUXsV2H58lqoj0rO84. Than call the function described. Worked.

If is there another way to create the structure of the database that make the deletion of older messages of all users easier let me know... For example, may be is it better to try to create a node with the timestamp that identify each day of the year?

Gustavomcls
  • 1,655
  • 2
  • 12
  • 20