Lyl*_*yla 6 android transactions firebase firebase-realtime-database
我正在开发一个应用程序,它在Firebase文档中给出的博客文章示例中执行与星数类似的操作,我对轮询系统的设计以及是否使用有疑问.
从示例中,帖子的数据如下所示:
postid {
// some data here about the post, author, id, etc,
starCount : <an integer count of the stars>,
stars : {
<user who starred> : true,
<user who starred> : true,
// ... and so on, basically a list of all the users who starred the post
}
}
Run Code Online (Sandbox Code Playgroud)
文档使用事务来更新星号:
private void onStarClicked(DatabaseReference postRef) {
postRef.runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
Post p = mutableData.getValue(Post.class);
if (p == null) {
return Transaction.success(mutableData);
}
if (p.stars.containsKey(getUid())) {
// Unstar the post and remove self from stars
p.starCount = p.starCount - 1;
p.stars.remove(getUid());
} else {
// Star the post and add self to stars
p.starCount = p.starCount + 1;
p.stars.put(getUid(), true);
}
// Set value and report transaction success
mutableData.setValue(p);
return Transaction.success(mutableData);
}
@Override
public void onComplete(DatabaseError databaseError, boolean b,
DataSnapshot dataSnapshot) {
// Transaction completed
Log.d(TAG, "postTransaction:onComplete:" + databaseError);
}
});
}
Run Code Online (Sandbox Code Playgroud)
因为采用了交易的双方starCount
,并stars
似乎需要是同一对象的一部分.为什么?因为我想同时使用交易并确保自动化.确保自动性的另一个选项是多路径更新,但是如注释中所述,您不能使用带有转换的多路径更新.您可以访问mutableData
(在这种情况下是post对象),就是这样.
所以如果starCount
并且stars
必须存储在同一个位置,我不明白starCount的要点.每当你得到一个帖子对象时,它都会包含stars
所有出演它的人的列表.为什么不完全删除starCount并获得星星列表的大小?这有什么不高效的吗?
在这种情况下,主演/取消明星的东西就像p.stars.put(getUid(), true);
和p.stars.remove(getUid());
.如果我这样做,我认为不需要交易,因为我不再有多个用户更新"计数器"对象.我可以在p.stars.put(getUid(), true);
声明中使用一个事务,但对我来说,尝试在两个不同的设备上播放/解除某些内容的同一个用户似乎不太可能,即使他们这样做了,就我所知,这不会是灾难性的.
那我在这里错过了什么?为什么在这里使用交易以及存储和手动跟踪starCount会增加哪些好处?我可以看到将stars
用户列表存储在数据库中其他位置的性能优势,如此示例所示,但随后事务将无法工作.
任何见解将不胜感激,谢谢!
在我们努力创建一个可从中获取文档示例的工作示例应用程序时,我们确实可能创建了一种不合理(但功能性)的交易用途。
我建议查看我对这个问题的回答,以获得使用多位置更新和服务器端安全规则进行安全计数的更合理(但绝对复杂)的方法。
但总的来说,在这种情况下,我总是建议将投票逻辑与计数逻辑分开。因此,当用户对帖子投票时,您可以在数据库中写入一条简单的记录来记录他们的操作:
votesQueue
<push id>
<uid>: true
Run Code Online (Sandbox Code Playgroud)
然后你有一个小型服务器脚本(例如firebase 队列工作程序)来侦听该队列并聚合投票数。
这种方法在使用 Firebase 时非常常见,并且使事情变得简单得多。您可能很容易想象如何保护这两个节点(votesQueue
和voteTotals
),而我可以向您保证,我上面链接的答案中的解决方案给我带来了相当大的维护麻烦。
归档时间: |
|
查看次数: |
395 次 |
最近记录: |