Deleting docs in cloud Firestore - firebase

I'm trying to code a todo App linked with cloud firestore. I want that when i tap on my tile which is a Gesture Detector, the task is deleted on firestore but it won't work.
Here's my code for my Function i use and all things that are necessary.
final _firestore = FirebaseFirestore.instance;
///
void deleteTask(){
_firestore.collection("todos").doc().delete();
}
///
child: GestureDetector(
onLongPress: (){
deleteTask();
},
child: Container(

When you are setting new doc Firebase probably this kind of code you use:
var db = FirebaseFirestore.instance;
DocumentReference ref = db.collection('tasks').doc();
ref.set(
{'field': data},
);
// save your ref.id here in order to let user remove the task eventually
This piece of code you wrote just puts a new document on a field. Now when you create or populate your Task class, you need to obtain document ID in order to delete it.
removeTask(String documentID) async {
var db = FirebaseFirestore.instance;
DocumentReference ref = db.collection('tasks').doc(documentID);
ref.delete();
}
// ref.id gives you the doc ID. Put it in your Task class when fetching docs
// so if user wants to delete any document, he/she can delete it.

Related

Flutter-Firestore: - Code to retrieve data from firestore then save/use it

I am very new to Dart, and coding in general. I have produced this code after watching tutorials on YouTube. For the most part, I have been able to troubleshoot most of my problems on my own, here I feel I need some help. I wanted to extract all the fields from a document and use it. I have tried a few codes but there is no proper solution anywhere online.
Here is the code I used to retrieve it:-
documentID = '9zjwixClgwR1Act1OlPK'
firebaseGetData(documentID){
firebaseFirestore.collection('course').doc(documentID).get().then((value) {
print(value.data());
});
}
Here is my database file structure:-
I want to store all the fields in variables and use them. please help me with the correct code, please.
There are two ways to retrieve data stored in Cloud Firestore. Either of these methods can be used with documents, collections of documents, or the results of queries:
Call a method to get the data
const docRef=doc(db,’course’,'9zjwixClgwR1Act1OlPK')
getDoc(docRef)
.then((doc) => {
console.log(doc.data(),doc.id)
})
Set a listener to receive data-change events.
To get real-time data when you set a listener, Cloud Firestore sends your listener an initial snapshot of the data, and then another snapshot each time the document changes.
const docRef=doc(db,’course’,'9zjwixClgwR1Act1OlPK')
onSnapshot(docRef,(doc) => {
console.log(doc.data(),doc.id)
})
For more information, kindly check link1 & link2
Firstly you need to create firestore instance. Your function must be async and return a Future value. Also, you can check this document.
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
Future<Map<String, dynamic>> firebaseGetData({required String documentID}) async {
DocumentSnapshot ds =
await _firestore.collection("course").doc(documentID).get();
Map<String, dynamic> data = ds.data() as Map<String, dynamic>;
print(data["videoDescription"] as String); // check if it null or not
return data;
}
// creating a instance variable
final CollectionReference firestoreInstance =
FirebaseFirestore.instance.collection('course');
void _loadUserData() async {
await firestoreInstance.doc(documentID).get().then((event) {
// you can access the values by
print(event['isDOne']);
print(event['lastViewedOn']);
print(event['lectureNo']);
print(event['videoDescription']);
print(event['videoUrl']);
});
}
call the _loadUserData() function whenever you need to fetch the data.

Flutter - Deleting a document in Firestore leads to the deletion of a random document and not the selected one

The 'utenti' (users) collection contains a document for each user which in turn contains the 'salvataggi' (saves) collection to save objects within the app.
Each document inside 'salvataggi' (saves) has an automatically generated id containing a series of data (String to be precise).
Documents within 'salvataggi' (saves) can be added by saving objects created from two other collections always in FIrestore.
When, through a button, I want to delete an object from the 'salvataggi' (saves) collection, a random document is deleted and not the one corresponding to the object.
Screenshot of Firestore
Object 1
final CollectionReference _usersRef =
FirebaseFirestore.instance.collection('utenti');
final User _user = FirebaseAuth.instance.currentUser;
//Add
Future _addToSaved() {
return _usersRef.doc(_user.uid).collection('salvataggi').doc().set({
'fonte': elenco.fonte,
'title': elenco.title,
'url': elenco.urlAvv,
'imageEv': elenco.urlAvv,
'p1': elenco.iconaProspettiva1,
'p1url': elenco.urlProspettiva1,
});
}
//Remove
Future _removeFromSaved() async {
CollectionReference userSaved =
_usersRef.doc(_user.uid).collection('salvataggi');
QuerySnapshot querySnap = await userSaved.get();
querySnap.docs[0].reference.delete();
}
Object 2
final CollectionReference _usersRef =
FirebaseFirestore.instance.collection('utenti');
final User _user = FirebaseAuth.instance.currentUser;
//Add
Future _addToSaved() {
return _usersRef.doc(_user.uid).collection('salvataggi').doc().set({
'fonte': widget.single.fonte,
'title': widget.single.title,
'url': widget.single.urlAvv,
'imageEv': widget.single.imageEvAvv,
'lastupdate': widget.single.dataAggiornamento,
'p1': widget.single.iconaProspettiva1,
'p1url': widget.single.urlProspettiva1,
});
}
//Remove
Future _removeFromSaved() async {
CollectionReference userSaved =
_usersRef.doc(_user.uid).collection('salvataggi');
QuerySnapshot querySnap = await userSaved.get();
querySnap.docs[0].reference.delete();
}
What am I doing wrong? Why does this happen?
When the user saves a document try saving the id of that document with it so whenever the user unsaved the document. You can pass the id of that unsaved document to firestore.
It will look something like this
Future _removeFromSaved(String docID) async {
CollectionReference userSaved =
_usersRef.doc(_user.uid).collection('salvataggi');
await userSaved.doc(docID).delete()
}
--UPDATE--
You can save document id by calling the then method after adding the document to firestore and then updating it
Future _addToSaved()async {
await _usersRef.doc(_user.uid).collection('salvataggi').add({
'fonte': widget.single.fonte,
'title': widget.single.title,
'url': widget.single.urlAvv,
'imageEv': widget.single.imageEvAvv,
'lastupdate': widget.single.dataAggiornamento,
'p1': widget.single.iconaProspettiva1,
'p1url': widget.single.urlProspettiva1,
}).then(docRef=>await _usersRef.doc(_user.uid).collection('salvataggi').doc(docRef.id).update({'id':docRef.id}));
}
querySnap.documents.first.reference.delete();
Use this instead of querySnap.docs[0].reference.delete();

New document being created instead of updated

I have an onPress on an edit page - it should update the document when edited and saved.
However, it is currently creating a new document with that data instead.
onPressed: () async {
//controllers...
await updateContact(context);
Navigator.pop(context, widget.contact);
}
.
final db = FirebaseFirestore.instance;
.
Future updateContact(context) async {
final uid = await TheProvider.of(context).auth.getCurrentUID();
await db
.collection('userData')
.doc(uid)
.collection('Contacts')
.doc(widget.contact.documentId)
.set({
'Name': oneController.text,
'PhoneNumber': int.tryParse(twoController.text),
'Location': threeController.text,
'Rating': int.tryParse(fourController.text),
'Instagram': fiveController.text,
'Birthday': int.tryParse(sixController.text),
'Notes': sevenController.text},
SetOptions(merge: true));
.
Contact.fromSnapshot(DocumentSnapshot snapshot) :
//...
documentId = snapshot.id;
I am not sure how to best resolve this.
Yes, using set() will override all the data already present in firestore.
and yes, using update is the way to go, but keep in mind not to call .toJson() on the entire object as update only takes the fields that are needed to be updated.
So if you update with the entire object, it'll create a new one again.
You could pass it like this
.update({'name': oneController.text, 'birth': twoContorller.text, 'email': threeController.text});
alternatively, you can also use set( setOptions: SetOptions(merge:true)) this will update only the fields that have changed in the document.

Flutter cloud firestore not updating automatically

I try to read listen to a stream from Firebase with this code:
visibleListsIds.forEach((final String listId) async {
final Stream<List<WishList>> wishListStream = sharedCollection()
.document(listId)
.snapshots()
.map((DocumentSnapshot documentSnapshot) {
log.d("updated Document Snapshot: ${documentSnapshot.data}");
return [
_getSerializers()
.deserializeWith(WishList.serializer, documentSnapshot.data)
];
});
wishListStreams.add(wishListStream);
});
Where sharedCollection() gives me access to the Firestore instance with the correct collection
I try to write to the collection, with this code
DocumentReference postRef = sharedCollection().document(wishList.listId);
firestore.runTransaction((Transaction tx) async {
DocumentSnapshot postSnapshot = await tx.get(postRef);
if (postSnapshot.exists) {
await tx.update(postRef,
_getSerializers().serializeWith(WishList.serializer, wishList));
} else {
await tx.set(postRef,
_getSerializers().serializeWith(WishList.serializer, wishList));
}
});
What happens:
I can write to Firebase but only one change at a time. When I do the next update, the last one gets reverted.
I can see the updated data only in the Firebase Console. The App does not show it and it does not show in the log at log.d("updated Document Snapshot: ${documentSnapshot.data}");.
When I modify data in the Firebase Console, I can also not see it change
BUT once I reload the App, all the Data syncs up to the current state of the Firebase Console
Anyone know why I do not get updates with the Stream?
Thanks for your help.
I use the Cloud Firestore Plugin:
cloud_firestore: ^0.13.0+1

FLUTTER | How to add data to an existing document in firestore

I'm using firestore to store data of my flutter application, and I made a function that creates a document in firestore automatically after the user login
Now I want the user when he fills this form , the data will be added in the same document where the user's email exists.
RaisedButton(
child: Text("Submit"),
onPressed: () {
final CollectionReference users = Firestore.instance.collection('users');
Firestore.instance
.runTransaction((Transaction transaction) async {
CollectionReference reference =
Firestore.instance.collection('users');
await reference
.add({"fullname": nameController.text, "PhoneNumber": phoneController.text, "adresse": adressController.text});
nameController.clear();
phoneController.clear();
adressController.clear();
});}
I tried this code but it adds new document.
Specify document name before updating database.
Firestore.instance
.collection('Products')
.document('Apple')
.updateData({
'price': 120,
'quantity': 15
});
Here my price and quantity data are numbers. If yours are Strings put String values there.
Best practice is to use transaction.
Make sure that document reference is a reference to a file that you wish to update.
Firestore.instance.runTransaction((transaction) async {
await transaction.update(
documentReference, data);
};
It will make sure that update happens in order in case there are many clients doing it.
In the case of a concurrent edit, Cloud Firestore runs the entire transaction again. For example, if a transaction reads documents and another client modifies any of those documents, Cloud Firestore retries the transaction. This feature ensures that the transaction runs on up-to-date and consistent data.
More info here
Try .setData({"fullname": nameController.text, "PhoneNumber": phoneController.text, "adresse": adressController.text}, merge: true).
Update 2021:
You need to update the data to add it to an existing document.
var collection = FirebaseFirestore.instance.collection('users');
collection
.doc('doc_id') // <-- Doc ID where data should be updated.
.update({'age' : 20}) // <-- New data
.then((_) => print('Updated'))
.catchError((error) => print('Update failed: $error'));

Resources