删除早于几天的邮件 - 使用 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 天的行