android - 将字符串附加到 Firebase 实时数据库上的列表
问题描述
我想在 Firebase 实时数据库上的列表中附加一个字符串。(我的代码已经可以使用,但是有问题)
所以数据库看起来像这样:
message:
0: "some string"
1: "another string"
2: "some string"
但我认为这段代码的问题是,如果有人读取消息的数量然后想要写一条消息,那么当另一个用户同时写一条消息时就会出现问题(因为消息的数量会改变)。
FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myRef = database.getReference("message");
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
myRef.child(
String.valueOf(dataSnapshot.getChildrenCount())
).setValue("SOME STRING");
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
解决方案
出于几个原因,尝试在多用户 Firebase 中使用顺序数字索引(通常也称为数组索引或自动增量值)是一种反模式。
正如您自己已经注意到的那样,用户有可能会覆盖彼此的数据。但是,这可以通过使用 transaction来解决,如果您需要基于其现有值来属性值,这是一种可行的方法。JavaScript
DatabaseReference.transaction
方法的参考文档有这个示例,这正是您所需要的:// Increment Ada's rank by 1. var adaRankRef = firebase.database().ref('users/ada/rank'); adaRankRef.transaction(function(currentRank) { // If users/ada/rank has never been set, currentRank will be `null`. return currentRank + 1; });
Android 中的语法稍微复杂一些,但工作方式相同。
当一个事务工作时,这意味着应用程序只有在用户连接到服务器时才能工作。当他们离线时,交易将失败。
由于这些原因,Firebase 应用通常使用不同的机制来生成其密钥。API的内置push()
方法会生成一个唯一的、始终递增的密钥。虽然此键不如您的顺序数字键可读,但它们确实解决了上述两个问题,而无需您自己编写更多代码。添加push()
消息变得如此简单:
final DatabaseReference myRef = database.getReference("message");
myRef.push().setValue("SOME STRING");
请注意,这个主题已经涵盖了很多,所以我建议您也检查一下:
推荐阅读
- javascript - 使用javascript通过按钮复制和粘贴?
- java - 如何在按钮列表中选择一个按钮?
- php - PHP mysql - 生成不超过 50k 行限制的站点地图
- mysql - 用户变量未在子查询中更新
- c# - 初始化列表
内联定义 - elixir - 枚举地图时如何编写传递给 Enum.map 的函数?
- hybris - 将 Hybris Impex Remove 与灵活搜索相结合
- java - Android - 创建文件适用于 Android 5 但不适用于 Android 6 或更高版本
- c# - 从另一个类更改表单上的标签
- wordpress - 我可以在代码中为我的自定义帖子类型设置注册的自定义分类吗?