Firebase realtime, list ids by date of children below - firebase

how do I list the ids in Firebase realtime according to the lastpost date below?
Table structure is in the attached image.
Image
Image
const userRef = database().ref(
'messages/180/Se2vRuZ0ZfaiUzpIX7L8XyXuyj42',
);
userRef.on('value', snapshot => {
console.log(snapshot)
})

Related

Flutter Firebase Pagination - Nested Query

I am relatively new to the Flutter world and need some help in efficiently querying a nested Firebase query with pagination in Flutter.
I am building an app where I have a few thousand of user selected documents in collectionA (selected from >100k documents from collectionB) and need to loop through a chunk of 10 documents (whereIn limit of 10) queried via stream. My current implementation (snippet below) takes a list of document ID's "d" and chunks in a list of 10 via quiver/iterables. The drawback of the methodology is that it reads thousands of user documents upfront before displaying it in the app. I would like to use a pagination and control the reads.
Would you suggest a solution (with a code snippet) on how to use the pagination through thousands of user selected documents?
Future<List<Article>> fbWhereGT10Article(
String collection, String field, List<dynamic> d) async {
final chunks = partition(d, 10);
// print(chunks);
final querySnapshots = await Future.wait(chunks.map(
(chunk) {
Query itemsQuery = FirebaseFirestore.instance
.collection(collection)
.where(field, whereIn: chunk);
// .orderBy('timestamp', descending: true);
return itemsQuery.get();
},
).toList());
return querySnapshots == null
? []
: await Stream.fromIterable(querySnapshots)
.flatMap((qs) =>
Stream.fromIterable(qs.docs).map((e) => Article.fromFirestore(e)))
.toList();
}

How to change the value of array field in firebase flutter?

I have an array containing list of image URL in firestore. I want to delete the specific image of certain index when user clicks the delete button. This is how my firebase image array looks like Here's what i've tried
FirebaseFirestore
.instance
.collection(
'adsPost')
.doc(widget.id)
.update({
'${images[_current]}':
''
}).whenComplete(() {
print(
'image removed from firestore');
});
You have two options, to remove it from the list in your app, and then update your firebase document with the new modified listed after the image was deleted.:
.update({"images": images.remove(images[_current])});
Or delete it from Firebase:
.update({"images": FieldValue.arrayRemove([images[_current]])})

Flutter Firebase How to get random document

I am trying to get some random posts from Firebase. But i am unable to get random document id.
Is there any way to retrieve data from Firebase like this :-
getRandomData() async {
QuerySnapshot snapshot = await posts
.document(random.id)
.collection('userPosts')
.getDocuments();}
i am trying to say that. Now i am able to get documentID normally not in italics.so now how can i get random documentID from Firebase.
List documentIds in a list first.
var list = ['documentId1','documentId2','documentId3'];
var element = getRandomElement(list);
Then query the documentSnapshot
You can first get all documents in you collection.
Try this code:
async getMarker() {
const snapshot = await firebase.firestore().collection('userPosts').get();
const documents = [];
snapshot.forEach(doc => {
documents[doc.id] = doc.data();
});
return documents;
}
Next, from return documents you can create a list of documents id and get random numbers (document id) from this list.
The main problem here that's going to prevent you from moving forward is the fact that you don't actually have any documents nested immediately under "posts". Notice that the names of the documents are in italics. That means there isn't actually a document here at all. The reason why they are show, however, is because you have a subcollection "userPosts" nested under the path where that document ID exists.
Since you don't have any documents at all under "posts", the usual strategies to find a random document won't work at all. You're going to have to actually populate some data there to select from, or find another way to select from the data in the subcollections.
firestore()
.collection('SOURCE')
.doc(props?.route?.params?.data?.id)
.collection('userPosts')
.get()
.then(querySnapshot => {
querySnapshot.forEach(documentSnapshot => {
console.log('User ID: ', documentSnapshot.id, documentSnapshot.data());
})
})

Firebase Query Collection And Merge Subcollection Data

I'm trying to figure out a way to get a collection of documents along with their subcollection data.
For example, my tree is...
-locations
-{locationId}
-historic
-april
-airTemp: 12.4
-displayOrder: 4
-august
-airTemp: 14.5
-displayOrder: 9
-december
-airTemp: 13.5
-displayOrder: 12
etc..
...where locationId is a document and historic is the subcollection with monthly documents in it.
I know how to get the top level collection items and store it into an array but I want to add their subcollection data (i.e. the jan, feb, etc.) into each document as well.
var locations = []
let ref = db.collection('locations')
db.collection('locations').get()
.then(snapshot => {
snapshot.forEach(doc => {
let location = doc.data()
location.id = doc.id
location.name = doc.name
// get the historic subcollection data here
})
})
How can I get the combined data (collection and subcollection) from each object and then push it into an array?
bounty is wrong structure
each month should be its own object
There is no way, with the mobile/web client libraries, to get, in one query, the data of a Firestore document and the data of its sub-collection(s) documents.
There is even no way to get the list of the sub-collections of a document (with the mobile/web client libraries), see https://firebase.google.com/docs/firestore/query-data/get-data#list_subcollections_of_a_document
So you need to know the name of the sub-collections in order to query them, which is your case (name = 'historic').
You could do as follows. First you get all the parent documents and at the same time you use Promise.all() to query, in parallel, all the 'historic' sub-collections.
var db = firebase.firestore();
var promises = []
db.collection('locations').get()
.then(snapshot => {
snapshot.forEach(doc => {
let location = doc.data()
location.id = doc.id
location.name = doc.data().name
console.log(location);
promises.push(doc.ref.collection('historic').get());
})
return Promise.all(promises);
})
.then(results => {
results.forEach(querySnapshot => {
querySnapshot.forEach(function (doc) {
console.log(doc.id, " => ", doc.data());
});
});
});
Note that the order of the results array is exactly the same than the order of the promises array.
Also note that to get the value of a document item (e.g. name) you need to do doc.data().name and not doc.name.
First create an empty array, e.g. resultsArray = []. Use simple or compound queries to get at the documents that you want to read. Then iterate over the resultDocuments creating an resultObject recording whatever properties you want. Inside that iteration, .push(resultObject) to the results array.

Firebase collection query on multiple documents check

Is it possible in firebase firestore to get information about the multiple documents are available or using where query we are using react native.
userRef.where('number', '==', '123')
.where('number', '==', '1234')
.get()
.then(r =>{
r.forEach(n => console.log(n))
});
is it possible to get those two documents in response ?
if I use like single where its working fine, how can I use same thing for nested documents compare ?
If I understand your use-case correctly, you want to get exactly two users, where user one has the number 123 and user two has the number 1234.
Such query to my understanding is currently not possible with Firestore, but you can split them up into two queries and merge the result.
const userOne = userRef.where('number', '==', '123').get();
const userTwo = userRef.where('number', '==', '1234').get();
Promise.all([userOne, userTwo])
.then(result => {
/*
* expected output: Array [QuerySnapshot, QuerySnapshot]
* First QuerySnapshot is result from userOne "where"
* Second QuerySnapshot is result from UserTwo "where"
*/
const userOneResult = result[0];
const userTwoResult = result[1];
if (userOneResult.empty === false && userTwoResult.empty === false) {
// Get both your users here
}
})

Resources