I have cloud fire store object like this
"TestCollection" : ["Test1","Test"]
Now I want to update this array with FieldValue.arrayUnion
because if element is same then i don't want to do anything but if it is not then I would like to add element
docRef.updateData({"TestCollection":FieldValue.arrayUnion(["test"])})
but this statement gives the error like object can not have nested array
Can anyone please help or provide same kind of example to have look for syntax ?
I have found a solution.
Try this:
Firestore.instance
.collection('YourCollection')
.document('YourDocument')
.updateData({'array':FieldValue.arrayUnion(['data1','data2','data3'])});
If it still doesn't work, try to update your Firebase.
First open a terminal fetched to your flutter project, then:
cd ios
pod update Firebase
This solution is only for mac users.
New FlutterFire Update 2021
With the newest FlutterFire update there where lots of updates at the API but thankfully it hasn't changed that much for this problem. I'm talking about the newest plugins of Firebase for Flutter and specifically every plugin that is compatible with the new firebase_core ^0.7.0.
So the code looks similar:
FirebaseFirestore.instance
.collection("YourCollection")
.doc("YourDocument")
.update({
"anArray": FieldValue.arrayUnion(["data", "to", "append"])
});
The other way if you have List of objects
Future<void> updateUserNewGroup(List<Group> data , String id) {
List<Map> list=new List();
if(data !=null && data.isNotEmpty){
data.forEach((grp){
list.add(grp.toJson());
});
}
return ref.document(id).updateData({"groups": FieldValue.arrayUnion(list)}) ;
}
Following up on the existing answers, if the field does not exist you can use a set & merge. This can save you from checking if the field exists or not.
Firestore.instance
.collection('YourCollection')
.document('YourDocument')
.setData({
'array':FieldValue.arrayUnion(['data1','data2','data3'])
}, merge: true);
this is the code I used and it worked like a charm!
_firestore
.collection('x')
.document('xxxxxxxxxx')
.updateData({
'comments': FieldValue.arrayUnion([
{'comment': "comment goes here", 'sender': "xxxxxxxx#gmail.com"}
])
});
2023
Use .set() with SetOptions(merge: true)
await FirebaseFirestore.instance.collection('users').doc(userService.userId).set({
'lastLogin': FieldValue.serverTimestamp(),
'devices': FieldValue.arrayUnion([removeSpaces(deviceId)]),
}, SetOptions(merge: true));
Related
I need to query a collectionGroup with where clause and While doing it I stumbled on to a thing.
var payData = FirebaseFirestore.instance.collectionGroup("payment").where("balance", isNotEqualTo: 0);
While executing the above code when I tried to print payData it prints Instance of _JsonQuery. How to access the data inside that variable and what's its structure.
I think the above code is incorrect.
var payData = FirebaseFirestore.instance.collectionGroup("payment").where("balance", isNotEqualTo: 0).getDocuments();
After surfing I got through the above code but VSCode says it's an error in getDocuments()
So, What I need is to print the data that is in the variable for the query I used above.
getDocuments() was deprecated in favor of get() in version 0.14.0 of the cloud_firestore package (Release notes). You need to call this method on your Query, i.e. payData.
The get() method returns a Future, so you can use then() as follows:
FirebaseFirestore.instance
.collectionGroup("payment")
.where("balance", isNotEqualTo: 0)
.get()
.then((QuerySnapshot querySnapshot) {
querySnapshot.docs.forEach((doc) {
print(doc["<name_of_a_field_in_the_doc>"]);
});
});
However, most of the times you will use one of the approaches shown in the FluterFire doc: depending on whether you want to read the data once or listening to changes in realtime you will use a FutureBuilder or a StreamBuilder.
I want to check if a certain id in a collection.document.collection.document() is available in firebase flutter dart, if it is so I remove the id else I add that id in the database.
So my problem is accessing the id value, I have tried .contains method but was always returning false even if the value is present. How can I work around this
this my firestore design
Firestore.instance
.collection('postt')
.document(postsId)
.collection('type')
.document();
I don't know what is your firestore design look like but according to your description this example should work.
DocumentSnapshot doc = await FirebaseFirestore.instance.collection('posst')
.doc('postsId')
.collection('type')
.where('id',isEqualTo: 'your id')
.get();
if(doc.exists){
// todo
}else{
// todo
}
I have flutter code that I have been using for a while that I use to perform crud operations on my firestore documents. I have one situation where an update appears to be deleting a document. I have put a breakpoint in my code just before the update and hold a reference to the document in the firestore console. As soon as the update runs, the document is removed from firestore. Does this make sense? Is there any condition that would cause a document to be deleted when invoking a DocumentReference.update? Here is a snippet of my code showing the update I am trying to perform:
Future<void> updateInMyCartIndicator(
ShoppingListItem shoppingListItem) async {
logger.d("FSShoppingListItemHelper:updateInMyCartIndicator - ENTRY");
try {
CollectionReference shoppingListItemCollection =
FirebaseFirestore.instance.collection('shopping_list_items');
QuerySnapshot shoppingListQuery = await shoppingListItemCollection
.where("id", isEqualTo: shoppingListItem.id)
.get();
final DocumentReference docRefShoppingListItem =
shoppingListItemCollection.doc(shoppingListQuery.docs[0].id);
await docRefShoppingListItem
.update({'in_my_cart': shoppingListItem.inMyCart});
logger.d(
"FSShoppingListItemHelper:updateInMyCartIndicator - Update complete");
} catch (e) {
logger.d("FSShoppingListItemHelper:updateInMyCartIndicator - Exception");
print(e.toString());
}
}
I have tried to reproduce this behavior and no matter how did I update a document (empty HashMap as argument, null fields, etc..) it was not getting deleted. As such the most likely scenario is that the document gets deleted somewhere else in your code, probably as an unintended side effect.
Thanks for the response. I was able to get past this. Honestly, all I did was kill the simulator and my ide and the deleting stopped. I can’t explain why it was happening, but it has gone away.
I'm trying to create a Blocked Users list in my chat app using the latest versions of Flutter Beta channel (1.23.0-18.1.pre) and cloud_firestore 0.14.3.
Here's my data structure:
At first, I tried something like this (Hardcoded just to test), by filtering the messages I'm querying from Firestore. Firebase doesn't like this.
query: firestore.collection('messages')
.where('userId', whereNotIn: ['123456789', '987654321'] )
.where('hashtag', isEqualTo: hashTag)
.orderBy('submittedAt', descending: true),
reverse: true,
I get this error:
E/FLTFirestoreMsgCodec(24331): java.lang.IllegalArgumentException: Invalid query. You have an inequality where filter (whereLessThan(), whereGreaterThan(), etc.) on field 'userId' and so you must also have 'userId' as your first orderBy() field, but your first orderBy() is currently on field 'submittedAt' instead.
After doing some more reading, filtering on the client-side by just hiding the messages actually better suits my needs.
Unfortunately, I'm running in circles. I'm currently thinking I would map a stream to a list, and then do something like this:
if (message.userId is in the list) {
isBlocked = true;
} else {
isBlocked = false;
}
And then filtering out the messages if isBlocked is true. I tried hardcoding the values for that and it worked. BTW, Sorry for the pseudocode, but I deviated so many times that now I'm simply lost.
I was wondering if this was the correct approach? Any suggestions would be rad. I also tried using a future list from a stream but I couldn't get that to work either.
Future<Stream<List<BlockedUser>>> getBlockedIds() async {
Stream<List<BlockedUser>> list;
Stream<QuerySnapshot> snapshot = FirebaseFirestore.instance.collection('user').doc('id').collection('blocked').snapshots();
list = snapshot.map((query) => query.docs.map(
(doc) => BlockedUser(
id: doc.data()['id'])
).toList());
return list;
}
I can't get that to work since I don't know what to do with that list.
Thanks, everyone!
hi i am trying to increment a value when clicked the button if data is available in firestore this is my code bloc if you have any suggestion lmk please
int q = 0;
final snapShot = await Firestore.instance.collection('cart').document("LIihBLtbfuJ8Dy640DPd").get();
if(snapShot.exists){
q=q+1;
}
Firestore.instance.runTransaction((Transaction transaction) async {
await transaction.update(
Firestore.instance
.collection("cart")
.document("LIihBLtbfuJ8Dy640DPd"),
{
foodItem.name: {
'itemName': foodItem.name,
'imgUrl': foodItem.imageAssetPath,
'itemPrice': foodItem.price,
'quantity': q,
}
});
});
In November 2021, this worked for me.
FirebaseFirestore.instance.collection('users').doc(currentUser?.id).update({
'bronzeBadges': FieldValue.increment(2),
});
var quantityref = db.collection("cart").document("LIihBLtbfuJ8Dy640DPd");
// Increment the quantity field by 1.
quantityref.update({
"quantity" : firebase.firestore.FieldValue.increment(1)});
If your want to change a value based on the previous one, you have basically two approaches:
Make use of transactions. I see you're doing that but incorrectly, because you're fetching the current value outside of it, and it could change by the moment you run the update, causing data inconsistencies. I don't know about Flutter, but as far as I know, a Transaction in Firebase consists in a read operation followed by one or more write operations, and the value returned from the read will be the very last one and won't be changed before you finish the transaction, so you can be sure you're working with the latest one. I suggest you to read the Transactions docs.
increment method (recommended): See this see this answer for incrementing in Flutter
First of all, you need to get the desired document and its elements to update the document of fields. In your example, it is quantity.
First, get the document:
Firestore.instance
.collection('cart')
.document('documentID')
.get()
.then((DocumentSnapshot ds) {
// use ds, parse ds then access the quantity
});
After doing the job, you need to update the field. Thankfully, there is an updateData function in firestore instance.
db.collection('cart')
.document('documentID')
.updateData({'quantity': someQuantity});
Hope it helps.