update single record among multiple records by UserId in Back4App flutter - flutter

I am trying to update records in my Back4App database. The problem is that ..objectId = currentUser.objectId takes only the userid and there can be multiple records for the same id. Thus, I am unable to update a single record of that userid. I am trying to filter by te unique id of records "concatid" but nothing gets updated.
Future<void> updateTodo(String description, String dogName) async {
ParseUser? currentUser = await ParseUser.currentUser() as ParseUser?;
var concatid = currentUser!.objectId! + dogName;
await Future.delayed(Duration(seconds: 1), () {});
final todo = ParseObject('Todo')
..objectId = currentUser.objectId
..set('concatId', concatid)
..set('DogDescription', description);
await todo.save();
}
Here's the documentation about update methods, but it only takes into account a general approach where you can only set new data matching by objectId and assuming this is unique (which is not my case).

Related

Remove referenced document from array Field list type in a document

I have a collection in firebase called "community" and "users". All user records have a field "joinedCommunity" (a list of all joined communities).
I'm trying to figure a code that when a community is deleted, all user records are updated to only remove the community reference from "joinedCommunity" field list.
building this in flutterflow using custom action
onTap on a button in UI, the code is included as one of the actions before community document is deleted.
Future userRecordUpdate(DocumentReference community) async {
final instance = FirebaseFirestore.instance;
final batch = instance.batch();
var collection = instance.collection('users');
batch.update(collection, {
"joinedCommunity": FieldValue.arrayRemove([community])
});
await batch.commit();
}
You're using a CollectionReference, when what you want is a DocumentReference. As per the documentation, WriteBatch.update only works on a DocumentReference.
I have a few suggestions:
Try updating the field without using a WriteBatch. Use a for loop and a regular DocumentReference.update() call.
Then, update your code to use a WriteBatch to update the field. Also, keep in mind a batch is limited to 500 operations.
Finally, consider the security implications of allowing a client to be able to update any User document. You should probably update your security rules so that a user document can only be modified by that user. This code is probably something that should run in a Firebase Cloud Function that gets triggered whenever a community document is deleted.
the following code worked -
Future userRecordUpdate(DocumentReference community) async {
final instance = FirebaseFirestore.instance;
final batch = instance.batch();
var collection = instance.collection('users');
var snapshots =
await collection.where("joinedCommunity", arrayContains:
community).get();
for (var doc in snapshots.docs) {
batch.update(doc.reference, {
"joinedCommunity": FieldValue.arrayRemove([community])
});
}
await batch.commit();
}

Adding map in Firestore?

How can I append a new Map type in firestore?
void addUser() async {
final us = _firestore.collection("users").doc(_search.text);
us.update({
"requests": (
{_auth.currentUser?.email: rep}
),
});
}
Am using this method but the requests field in my firestore overwrites the previous one I want it to be appended. Any idea?
The update() method will always overwrite your previous field with the new one, so achieving this with one operation using the update() is not possible, however, you can always get the current field from the document, then update its value, then save it again in the document like this:
void addUser() async {
final us = _firestore.collection("users").doc(_search.text);
final currentDoc = await us.get(); // we get the document snapshot
final docDataWhichWeWillChange = currentDoc.data() as Map<String, dynamic>; // we get the data of that document
docDataWhichWeWillChange{"requests"]![_auth.currentUser?.email] = rep; // we append the new value with it's key
await us.update({
"requests": docDataWhichWeWillChange["requests"],
}); // then we update it again
}
But you should use this after being aware that this method will make two operations in your database, a get() and update().
If you want to record multiple values, an array is an appropriate type. So, you could use the .arrayUnion method to record multiple entries.
final washingtonRef = db.collection("cities").doc("DC");
// Atomically add a new region to the "regions" array field.
washingtonRef.update({
"regions": FieldValue.arrayUnion(["greater_virginia"]),
});

Flutter firestore returns length 0 while there is data in firestore

I have the following code in flutter:
QuerySnapshot querySnapshot =
await _firestore.collection("user1#gmail.com").get();
List Data = querySnapshot.docs.map((doc) => doc.data()).toList();
print("Length: ${Data.length}");
Here is my firestore database:
I get the following output:
I/flutter (11484): Length: 0
The Documents for each user email is variable, so I need the length of the documents. Also I need to get to the details of each document like content and title. How to do it? Thanks.
Could you try this:
int size = await FirebaseFirestore.instance.collection(collectionPath).get(GetOptions(source:Source.server))..size;
I will recommend finding a way to store the length of documents as a field in your Cloud Firestore database because calling the get function on a whole collection means filling up the mobile phone memory. (Say you have 500,000 users at least). This makes your app slow
You could have a field called count such that when you add a document, you can use the firebase transaction to update firebase.
For example:
// Create a reference to the document the transaction will use
DocumentReference documentReference = FirebaseFirestore.instance
.collection('users')
.doc(documentId);
return FirebaseFirestore.instance.runTransaction((transaction) async {
// Get the document
DocumentSnapshot snapshot = await transaction.get(documentReference);
if (!snapshot.exists) {
throw Exception("User does not exist!");
}
// Update the follower count based on the current count
// Note: this could be done without a transaction
// by updating the population using FieldValue.increment()
// Perform an update on the document
transaction.update(documentReference, {'followers': FieldValue.increment(1);});
// Return the new count
return newFollowerCount;
})
.then((value) => print("Follower count updated to $value"))
.catchError((error) => print("Failed to update user followers: $error"));
You can see more documentations here: FlutterFire

How to retrive all the documents of firestore at once using flutter?

I am building an Appointment Booking application want to retrieve all my documents from firestore at once on a button click. I used this:
Future<void> userAppointmentHistory() async {
String collectionName =
FirebaseAuth.instance.currentUser?.displayName as String;
String doc_id = "YyWqd9VlB1IdmYoIIFTq";
await FirebaseFirestore.instance
.collection(collectionName)
.doc(doc_id)
.snapshots()
.listen(
(event) {
print(
event.get("selectedDate"),
);
},
);
}
From the above code, I am getting only the specified document id details. So please help me modify the above code so that I get all the document details as I want to display these details on cards as my booked appointment history.
Here you are passing the doc id String doc_id = "YyWqd9VlB1IdmYoIIFTq";
You don't want to pass that if you want the full documents.
just pass the collection reference.
Follow the below code
fetchData() {
CollectionReference collectionReference =
FirebaseFirestore.instance.collection(collectionName);
collectionReference.snapshots().listen((snapshot) {
setState(() {
document = snapshot.docs;
});
print(document.toString);
});
}
Rudransh Singh Mahra,
It's as easy as putting text widget in our application.
Solution
You did it in right way but by mistake you have passed a specific id of documents in doc() as doc('YyWqd9VlB1IdmYoIIFTq'). you just need to remove that id from there and you may get your desired output.
What actually happens :
In your query you pass specific docId. So that it will returns that specified id document from your collection. To get all the documents from that collection you just need to do as follows,
Future<void> userAppointmentHistory() async {
String collectionName =
FirebaseAuth.instance.currentUser?.displayName as String;
// String doc_id = "YyWqd9VlB1IdmYoIIFTq";
await FirebaseFirestore.instance.collection(collectionName).doc().get()
}
And you will get your desired output if collectionName is valid and exist in firestorm database.

Firestore Firebase create fielID equal Document ID

Can anyone tell me how to create a field Id that is equal to the Document ID. I have done like below however is very inconsistent sometimes the documentID is equal field ID other times not. I want them to always be the save.
void saveOrders() async {
await _db.collection(_collectionOrders).add(
{
"id": _db.collection(_collectionOrders).document().documentID,
}
).then((value){
});
}
thanks in advance.
You could do this in two steps:
Create your document without the id:
DocumentReference doc = await _db.collection(_collectionOrders).add({'your': 'data'});
Update the newly created document and add the id property:
await doc.update({'id': doc.id});
You can now be sure that you inserted the right documentId.