如何在不覆盖的情况下向 Firebase Firestore 添加值?
Posted
技术标签:
【中文标题】如何在不覆盖的情况下向 Firebase Firestore 添加值?【英文标题】:How to add values to Firebase Firestore without overwriting? 【发布时间】:2018-08-29 04:14:10 【问题描述】:我有两个活动,我分别从这两个活动向 Firestore 添加数据。但是,每当我向 Firestore 添加第二个活动数据时,它都会覆盖第一个活动数据。我在两个活动中使用了以下代码:
firebaseFirestore.collection("Users").document(user_id).set(data)
如何停止覆盖?我想将两个活动数据保存在同一个user_id
。
【问题讨论】:
为user_id
下方的每个活动再添加一个孩子
如何添加孩子。你能告诉我..@Dumbo
【参考方案1】:
试试这个直接更新
db.collection('cities').doc('restaurants').update(
rating:"3.2"
);
只有字段等级会改变,其余字段保持不变。
假设您有 3 个字段,并且只想更改其中的 2 个,您也可以用不同的方式进行此操作
// You get the document 'restaurants' and then do the below
db.collection('cities').doc('restaurants').get().then((doc) =>
// Get the rating field string, parse it to a float, remove 0.4 from it and
// set it to a tmp variable
var tmpRating = parseFloat(doc.data()['rating']) - 0.4;
// Get the array of strings field 'menu' and set it to a tmp variable
var tmpMenu = doc.data()['menu'];
// Push 'spaghetti' string to the tmp array of strings( Can also put an
// adapting string variable instead of a specific string like 'spaghetti'
tmpMenu.push('spaghetti');
// Update only the specific fields 'rating' and 'menu' and keep the rest unchanged.
db.collection('cities').doc(doc.id).update(
rating: toString(tmpRating), // Don't forget to separate them by commas
menu: tmpMenu
);
);
【讨论】:
【参考方案2】:根据文档,您可以将merge:true
用作第二个参数,根据我的经验,问题通常在于您尝试使用相同的密钥存储不同的数据。
即使使用merge: true
也会始终使用您传入的值更新当前键。
Merge:true 仅当密钥不存在时才有效。我相信文档中的每个键都必须是唯一的。
为了测试它尝试使用不同的键传递(保持merge: true
作为第二个参数)数据,它将合并到现有的。
【讨论】:
【参考方案3】:有两种方法可以实现这一目标。第一个是使用Map
:
Map<String, Object> map = new HashMap<>();
map.put("yourProperty", "yourValue");
firebaseFirestore.collection("Users").document(user_id).update(map);
如您所见,我使用了update()
方法而不是set()
方法。
第二种方法是像这样使用模型类的对象:
YourModelClass yourModelClass = new YourModelClass();
yourModelClass.setProperty("yourValue");
firebaseFirestore.collection("Users").document(user_id)
.set(yourModelClass, SetOptions.mergeFields("yourProperty"));
如您所见,我使用了set()
方法,但我将SetOptions.mergeFields("yourProperty")
作为第二个参数传递,这意味着我们只对特定字段进行更新。
【讨论】:
你实现了更新值而不覆盖吗? ....我明白了,但是稍后我又遇到了另一个问题。我在布局中使用了 ScrollView。但它不会滚动全部内容。滚动后,它仍然在底部留下一些可滚动的部分。它在屏幕底部形成了一个不寻常的小空白。我该如何解决它 这基本上是另一个问题。为了遵守本社区的规则,请再次提出新问题,以便我和其他用户可以帮助您。 我的回答对您有帮助吗? @NadeemShaikh 我认为answer 可能会有所帮助。【参考方案4】:如果您知道用户文档已经存在于 firestore 中,那么您应该使用
firebaseFirestore.collection("Users").document(user_id).update(data)
如果你不知道文档是否存在,那么你可以使用
firebaseFirestore.collection("Users").document(user_id).set(data, merge:true)
这将执行数据的深度合并
您也可以使用子集合来做到这一点
【讨论】:
【参考方案5】:我建议您再添加一个文档或集合,以便为单个用户存储更多的数据值。 您可以为这两个活动创建一个文档引用:
firebaseFirestore.collection("Users").document(user_id+"/acitivity1").set(data);
//and
firebaseFirestore.collection("Users").document(user_id+"/acitivity2").set(data);
或者你可以为它创建一个子集合:
firebaseFirestore.collection("Users").document(user_id)
.collection("Activities").document("acitivity1").set(data);
//and
firebaseFirestore.collection("Users").document(user_id)
.collection("Activities").document("acitivity2").set(data);
更多关于分层数据there。
【讨论】:
以上是关于如何在不覆盖的情况下向 Firebase Firestore 添加值?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用 Firebase Cloud Messaging 控制台的情况下向 Flutter/Firebase Cloud Messaging 上的特定设备发送通知 [重复]
我开发了提醒应用程序,因此如何在不使用 firebase 的情况下向用户发送本地通知
如何在不覆盖现有样式的情况下向 WPF 自定义控件添加触发器?
如何在不阻止 textView 触摸的情况下向所有 UITextView 添加一个 UIGestureRecognizer