删除早于几天的邮件 - 使用 MAP 的时间戳

Posted

技术标签:

【中文标题】删除早于几天的邮件 - 使用 MAP 的时间戳【英文标题】:Delete messagem older tha n days - timestamp using 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 存在多个消息(例如)。 但我仍然没有找到如何只删除我需要的消息。 我怎样才能用我的数据库做到这一点?

【问题讨论】:

【参考方案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。比调用描述的函数。工作。

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

【讨论】:

以上是关于删除早于几天的邮件 - 使用 MAP 的时间戳的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL - 删除每个 idnumber 输入早于 x 天的行

Linux 删除早于相同时间的文件

如何删除时间戳超过 7 天的行

python redistimeseries 时间戳不能早于时间序列中的最新时间戳

SQL 时间戳查询:检查一个时间戳是不是早于另一个

Stripe 创建使用记录错误 - 时间戳必须早于订阅的当前周期结束时间 - Date.now()?