Reputation: 12606
I would like to know if specific document exists, update that document and if not create that document is possible in Firestore or not.
For example, user entered some tag with post, then look like this
Firestore.instance.collection('tags').document(tag here).updateData()
.
Is there any way if that document doesn't exist, then create method or do I have to check if exists before writing it?
Upvotes: 14
Views: 13248
Reputation: 268094
Use set
on the document and provide a SetOptions
with merge: true
. From the docs:
Sets data on the document, overwriting any existing data. If the document does not yet exist, it will be created.
If SetOptions are provided, the data will be merged into an existing document instead of overwriting.
var collection = FirebaseFirestore.instance.collection('collection');
collection
.doc('doc_id')
.set(yourData, SetOptions(merge: true));
Upvotes: 8
Reputation: 738
It appears that as of 2020-03-31, yes, you have to check whether or not the document exists first. setData(data, merge: true)
doesn't actually obey the merge
parameter. Here is the relevant GitHub issue
The behavior I'm getting is equivalent to a regular setData()
, so it silently overwrites any existing data. An expensive workaround:
final Firestore _db = Firestore.instance;
final collection = 'my_collection';
final documentId = 'my_document';
final snapShot = await _db.collection(collection).document(documentId).get();
if(snapShot.exists){
_db.collection(collection).document(documentId).updateData(myMap);
} else {
_db.collection(collection).document(documentId).setData(myMap);
}
Upvotes: 4
Reputation: 1771
You want to upsert and best way to do with is:
Future updateUserFirestore(
String name,
String dob,
String email,
String sex
) {
return _getUserDetailsDocumentRef().update({
'name': name,
'dob': dob,
'email': email,
'sex': sex
}).catchError((e) => {
_getUserDetailsDocumentRef().set({
'name': name,
'dob': dob,
'email': email,
'sex': sex
}, SetOptions(merge: true))
});
}
Upvotes: 1
Reputation: 3632
Update
on newer Firebase SDK the syntax changed; Firebase is FirebaseFirestore and setData is deprecated in favor of set + SetOptions.
FirebaseFirestore.instance.
collection('tags').
document(tag).
set(data, SetOptions(merge: true))
@Doug is right, there is an option in the Flutter Firestore API:
Firestore.instance.
collection('tags').
document(tag here).
setData(data, merge: true)
From the doc:
setData(Map<String, dynamic> data, {bool merge: false}) → Future<void>
Writes to the document referred to by this DocumentReference. If the document does not yet exist, it will be created.
If merge is true, the provided data will be merged into an existing document instead of overwriting.
Compare that with the doc from updateData
, which explicitly fails.
updateData(Map<String, dynamic> data) → Future<void>
Updates fields in the document referred to by this DocumentReference.
If no document exists yet, the update will fail.
Upvotes: 31
Reputation: 317712
I don't know how it works with Flutter specifically (I haven't written a line of Dart in my life), but the other client APIs allow a second argument to set() (or in your case setData()) that allows a document to be either created if not existing, or merged in the case that it already does.
See the documentation for examples in other languages. It might just be a matter of passing { merge: true }
as the second argument, like the web example, or possibly use of SetOptions.merge()
like Java.
Upvotes: 11