【问题标题】:Delete messagem older tha n days - timestamp using MAP删除早于几天的邮件 - 使用 MAP 的时间戳
【发布时间】:2017-04-27 16:02:25
【问题描述】:

我正在尝试使用时间戳将旧消息删除到 FriendlyChat 中。 我正在使用这篇文章How to delete firebase data after "n" days 来尝试解决。 我遇到的问题:我的 firebase 数据库的这段代码正在删除所有消息,而不仅仅是我需要的消息。

我的 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"
      }
    }
  }
}

我的sn-p代码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

这里的区别是我在 date 中的时间戳是在 "dateCreatedGu 而不是直接在消息上,因为我使用 Map 来存储时间戳.

怎么了?如何正确删除我需要的消息 - 例如超过 30 天的消息? 我尝试将 30 天到 30 秒的时间段形式更改为 cutoff = new Date().getTime() - TimeUnit.MILLISECONDS.convert(30, TimeUnit.SECONDS); 以验证代码。

我尝试从addValueEventListener 更改为添加ChildEventListener...

我知道orderByValue 用于当您不是读取具有属性的对象而是直接读取属性时使用。 我知道在这种情况下,最好使用 orderbyKey 优化代码,因为键在时间期间按字母顺序存储 - 跳跃值) - 对于优化时间戳的搜索也很有用。 我知道addChildEventListener 尝试读取数据库中的每个值 f 存在多个消息(例如)。 但我仍然没有找到如何只删除我需要的消息。 我怎样才能用我的数据库做到这一点?

【问题讨论】:

    标签: android firebase timestamp firebase-realtime-database


    【解决方案1】:

    由于您嵌套了时间戳,因此您需要在查询中按该嵌套属性进行排序:

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

    【讨论】:

    • 另外,我在 JSON 中看不到 timestamp。我怀疑 Gustavomcis 打算使用 date
    • 好收获。当我输入代码时,我已经跑完了。我修好了。
    • Query oldItems = mFirebaseDatabaseReference.orderByChild("dateCreatedGu/date").endAt(cutoff) 的代码仍在删除所有消息。我用过 (30, TimeUnit.DAYS);并且仍在删除几秒钟前的消息,并且也开始删除所有新消息。我重命名了启动删除消息过程的按钮的名称。因为现在,不用按下删除消息的按钮,现在所有的消息都开始被立即删除。是否有来自此按钮的信号未捕获开始该过程?消息仍会被删除。
    • 听起来您有另一个进程正在删除邮件。
    • snapshot.getRef() 给出:= nameOfApp.firebaseio.com/messages - 我在这里更改了 nameOfApp 这个词。应用程序停止从可能的另一个进程中删除消息,但仍在删除地址中的所有消息:snapshot.getRef() 而是仅删除查询中指定的消息。 – 古斯塔沃姆cls
    【解决方案2】:

    不删除所有节点的解决方案是: 来自

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

    改成

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

    或者这样做

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

    因为代码 itemSnapshot.getRef() 正在返回所有消息的父节点,即“Bl0AiMMUXsV2H58lqoj0rO84”,这就是为什么当您执行 removeValue() 方法时,所有消息都将被删除。您的数据库引用应位于消息节点下的 id(我假设这是一个 uid)处。

    Firebase 团队帮助我解决了这个问题。

    要使用此代码,必须首先调用另一个发现节点名称的函数,在本例中为节点:Bl0AiMMUXsV2H58lqoj0rO84。比调用描述的函数。工作。

    如果有另一种方法来创建数据库结构,以便更轻松地删除所有用户的旧消息,请告诉我... 例如,尝试创建一个带有标识一年中每一天的时间戳的节点会更好吗?

    【讨论】:

      猜你喜欢
      • 2014-02-07
      • 2019-12-08
      • 2017-05-27
      • 1970-01-01
      • 2016-05-23
      • 1970-01-01
      • 1970-01-01
      • 2020-05-22
      相关资源
      最近更新 更多