2016-12-12 12 views
2

タイムスタンプを使用して古いメッセージをFriendlyChatに削除しようとしています。 私はこの投稿を使用して解決しようとするHow to delete firebase data after "n" daysです。 問題:私のfirebaseデータベースへのこのコードは、必要なメッセージだけでなく、すべてのメッセージを削除しています。古いメッセージの削除 - MAPを使用したタイムスタンプ

マイfirebaseデータベースの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" 
     } 
    } 
    } 
} 

私のスニペットコードアンドロイド:

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 

違いはここに日付への私のタイムスタンプがメッセージに「dateCreatedGuではないです地図を使ってタイムスタンプを保存したからです。

どうしたのですか?必要なメッセージ、たとえば30日以上経過したメッセージだけを正しく削除するにはどうすればよいですか? 303日から30秒の期間形式をcutoff = new Date().getTime() - TimeUnit.MILLISECONDS.convert(30, TimeUnit.SECONDS);に変更してコードを確認しようとしました。

は、私は私はあなたが属性を持つオブジェクトを読んだが、 直接属性を読んでいないとき orderByValueが使用されていることを理解 ChildEventListener...

追加するaddValueEventListenerから変更しようとしました。 このケースでは、orderbyKeyを使用してコードを最適化するほうがよいと理解しました。なぜなら、キーはタイムジャンプ値の間にアルファベット順に格納されるからです) - タイムスタンプの検索を最適化するのにも役立ちます。 addChildEventListenerは、データベース内の各値を読み取ろうとしていることが理解されています。たとえば、複数のメッセージが存在します。 しかし、私はまだ必要なメッセージだけを削除する方法が見つかりませんでした。 私のデータベースでどうすればいいですか?

答えて

0

すべてのノードを削除しないためにsolutonは次のとおりです。

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

変更〜

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

またはこれを行う

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

コードitemSnapshot.getRefは()あなたがたremoveValue()メソッドを実行するとき、すべてのメッセージが削除される理由です「Bl0AiMMUXsV2H58lqoj0rO84」であるすべてのメッセージの親ノードを返しているので。データベース参照は、メッセージノードの下にあるid(私はこれがuidであると仮定します)になければなりません。

Firebaseチームは私にこれを解決するのを手伝ってくれました。

このコードを使用するには、ノードの名前を検出する別の関数(この場合はノード:Bl0AiMMUXsV2H58lqoj0rO84)を最初に呼び出す必要があります。記述された関数を呼び出すよりも。働いた。

データベースの構造を作成して、すべてのユーザーの古いメッセージを簡単に削除できる別の方法がある場合は、教えてください。 たとえば、次のようなノードを作成するとよいでしょう。年の各日を識別するタイムスタンプ?

1

あなたはタイムスタンプを入れ子になっているので、あなたがあなたのクエリでそのネストされたプロパティで注文する必要があります。

Query oldItems = mFirebaseDatabaseReference.orderByChild("dateCreatedGu/date").endAt(cutoff); 
+0

また、私はJSONに 'timestamp'も表示しません。私はGustavomcisが 'date'を使用しようと思っています。 –

+0

良いキャッチ。私はコードを入力していたときに私は不足していた。それを私が直した。 –

+0

クエリoldItems = mFirebaseDatabaseReference.orderByChild( "dateCreatedGu/date")のコード。endAt(cutoff)は、依然としてすべてのメッセージを削除しています。私は(30、TimeUnit.DAYS)を使用しました。数秒前からメッセージを削除して、新しいメッセージもすべて削除し始めました。私は、メッセージを削除するプロセスを開始したボタンの名前を変更しました。今、メッセージを削除するボタンを押すことなく、今すぐすべてのメッセージがすぐに削除され始めました。このボタンから信号を受信して​​プロセスを開始することはできませんか?メッセージは削除されます。 – Gustavomcls