Retrieve Firestore Auto generated Document ID from field [duplicate] - flutter

QuerySnapshot querySnapshot = await _collectionRef
.limit(1)
.orderBy('date')
.getDocuments();
var list = querySnapshot.documents;
querySnapshot.documents.map((document) {
print('Document : $document'); // not printing anything.
});
if(list.length > 0) {
print('ID : ${list[0].documentID}'); // not working
}
This is the exact code i tried...
What is the mistake in the code?

According to the API documentation, DocumentSnapshot has a documentId property, so I would expect this to work:
querySnapshot.documents[0].documentID

product.id
documentID is deprecated and shouldn't be used. Deprecated in favor of .id.
Try replacing the use of the deprecated member with the replacement.

For DocumentSnapshot,
document.documentID

Also, use backticks when stringinterpolating.
print('ID : ${list[0].documentID}'); // not working
print(`ID : ${list[0].documentID}`); // working

For DocumentSnapshot,
document.id

Related

Flutter how to delete field from firebase array

I am trying to delete a field from my firebase array. I am using this code but it deletes then whole activity array.
FirebaseFirestore.instance
.collection(
widget.user.user.uid)
.doc(documentName)
.update({
"activities":
FieldValue.delete()
Instead I want to delete a specific field from 'activities' like activities[2]. How can I do to fix this?
To remove an item at a specific index you can use the arrayRemove method from FieldValue
FirebaseFirestore.instance.collection(widget.user.user.uid).doc(documentName).update({
"activities": FieldValue.arrayRemove("itemToRemove")
})
You should try using FieldValue.arrayRemove() method and then pass the value that you want to remove using this :
var val=[]; //blank list for add elements which you want to delete
val.add('$addDeletedElements');
FirebaseFirestore.instance
.collection(
widget.user.user.uid)
.doc(documentName)
.update({
"activities":
FieldValue.arrayRemove(val])
You have to tell firebase full path like this
FirebaseFirestore.instance
.collection("chat_dialog")
.doc("India")
.collection("dialog_details")
.where(['firestore_id'].contains('your_value'))
.get()
.then((value) {
print(value.docs.length);
for (var element in value.docs) {
print(element.id);
}
});

Flutter - Can't get collection from firestore

_getLatestCompletedWorkout() async {
try {
QuerySnapshot workouts;
workouts = await FirebaseFirestore.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser!.uid)
.collection('workouts')
.get();
for (var workout in workouts.docs) {
print('WORKOUT = ');
print(workout);
}
.....
What I really need is to get the last document saved; but before that I am just trying to fetch the "workouts" collection; the workouts.docs list always has 0 items. There are 2 items in the DB. What is wrong with this code? Also how to get the last saved item?
As mentioned by Frank :
You can refer Alex answer here :
The simplest way to achieve this is to add a date
property to each object in your collection, then simply query it
according to this new property descending and call limit(1) function.
This is the required query:
this.historyRef = afs.collection<History>('history', ref => ref.orderBy('date', 'desc').limit(1));
this.history = this.historyRef.snapshotChanges().map(actions => {
return actions.map(a => {
const data = a.payload.doc.data() as Hisotory;
const docId = a.payload.doc.id;
return { docId, ...data };
});
});
This has been found since cloud_firestore updates that prevent app that not regiter in App Check to take updates seriously "but it store it with lighter id color" which Protect your Cloud Firestore resources from abuse, such as billing fraud or phishing
Kindly check and ensure your app is registered inside App Check in Firebase console

Firestore new document inside writebatch

I have a couple of writes that I want to be done together.
So I used a write batch.
Since the write batch requires a document reference, I have been creating the document before that write batch operation.
DocumentReference accountHistoryDoc = await queryResult.reference.collection('accountHistory').add({});
This led to many empty documents. Since I'm still testing and debugging the app, I assume because of an exception after the creation of the document.
How can I make sure that an empty document isn't created in the case of failure?
I'm thinking of changing this line
wb.set(
accountHistoryDoc, // Change this line
{
'account': newAccount,
'serverTimestamp': FieldValue.serverTimestamp(),
'type': 'hisab',
},
);
to
wb.set(
await subscriberDoc.collection('accountHistory').add({}),// new line
{
'account': newAccount,
'serverTimestamp': FieldValue.serverTimestamp(),
'type': 'hisab',
},
);
Is this my thinking correct?
Rest of code:
QuerySnapshot query = await FirebaseFirestore.instance
.collection(CurrentUser.getCurrentUser().uid)
.where('mobile', isEqualTo: mobile)
.get();
QueryDocumentSnapshot queryResult = query.docs.first;
DocumentReference subscriberDoc = queryResult.reference;
DocumentReference accountHistoryDoc = await queryResult.reference.collection('accountHistory').add({}); // < -- new empty document here
WriteBatch wb = FirebaseFirestore.instance.batch();
// update the total account
wb.update(
subscriberDoc,
{
'totalAccount': subscriber.totalAccount + newAccount,
},
);
// add new document in account history
wb.set(
accountHistoryDoc,
await subscriberDoc.collection('accountHistory').add({}),
{
'account': newAccount,
'serverTimestamp': FieldValue.serverTimestamp(),
'type': 'hisab',
},
);
If you call CollectionReference.doc() without an argument, it generates a new unique DocumentReference without already creating that document in the database. You can then use this DocumentReference to create the new document inside the batched write.
Also see the documentation for the FlutterFire doc() method.

Map Firestore DocumentSnapshot to Properties In a Class

I have code like this for QuerySnapshot to get documents in collection that works good.
List<DaftarHazard> _userHazardFromSnapshot(QuerySnapshot snapshot) {
return snapshot.documents.map((hazards) {
return DaftarHazard(
waktuHazard: hazards.data['waktuHazard'],
judulHazard: hazards.data['judulHazard'],
isiHazard: hazards.data['isiHazard'],
fotoHazard: hazards.data['fotoHazard'],
namaPelapor: hazards.data['namaPelapor'],
lokasiHazard: hazards.data['lokasiHazard'],
statusHazard: hazards.data['statusHazard']);
}).toList();
}
Stream<List<DaftarHazard>> get userHazardAsSuper {
return userHazards.snapshots().map(_userHazardFromSnapshot);
}
But then I need to Map DocumentSnapshot to class properties.
I don't know how to get this done.
How can I do this using the same method that I use for the QuerySnapshot?
The code above I get from collections.
Code below is the one I use to get fields in a document
Stream<List<UserDetails>> get userDetails {
return userData.document(uid).snapshots().map(_userDetailsFromSnapshot);
}
and using this to map to the properties
List<UserDetails> _userDetailsFromSnapshot(DocumentSnapshot snapshot) {
return snapshot.data.map((item) {
return UserDetails(
name: details.['name'],
email: details.data['email'],
);
}).toList();
}
But code above does not work.
Found the solutions here:
Net Ninja
You to extract the data from your DocumentSnapshot.
List<DaftarHazard> _userHazardFromSnapshot(QuerySnapshot snapshot) {
return snapshot.documents.map((hazards) {
return DaftarHazard(
waktuHazard: hazards.data['waktuHazard'] != null ? WaktuHazard.fromData(hazards.data['waktuHazard'].data) : null,
judulHazard: hazards.data['judulHazard'],
isiHazard: hazards.data['isiHazard'],
fotoHazard: hazards.data['fotoHazard'],
namaPelapor: hazards.data['namaPelapor'],
lokasiHazard: hazards.data['lokasiHazard'],
statusHazard: hazards.data['statusHazard']);
}).toList();
}
And replace each property for its own object instead of DocumentSnapshots.
I'm not sure of the structure that you want, but basically, you just need to access the data property of your DocumentSnapshot and parse it accordingly.
Found the solution for getting field and value from a specific document in firestore here
[Net Ninja][1]

How to get firestore document ID from document snapshot?

QuerySnapshot querySnapshot = await _collectionRef
.limit(1)
.orderBy('date')
.getDocuments();
var list = querySnapshot.documents;
querySnapshot.documents.map((document) {
print('Document : $document'); // not printing anything.
});
if(list.length > 0) {
print('ID : ${list[0].documentID}'); // not working
}
This is the exact code i tried...
What is the mistake in the code?
According to the API documentation, DocumentSnapshot has a documentId property, so I would expect this to work:
querySnapshot.documents[0].documentID
product.id
documentID is deprecated and shouldn't be used. Deprecated in favor of .id.
Try replacing the use of the deprecated member with the replacement.
For DocumentSnapshot,
document.documentID
Also, use backticks when stringinterpolating.
print('ID : ${list[0].documentID}'); // not working
print(`ID : ${list[0].documentID}`); // working
For DocumentSnapshot,
document.id