How to use Array contains in the same array fields in firebase for flutter - flutter

I have a chat collection.
each document has an array with two user id's.
my goal is to get the chat that has both user sys id's
I tried running the following but I got an error because we cant use two 'arrayContains' in one query.
Is there any way to perform such query?
here is an image of the data structure
Future getChat({required List userIdsArr}) async {
var docId = '';
userIdsArr.sort((a, b) {
return a.compareTo(b);
});
var filter1 = userIdsArr[0];
var filter2 = userIdsArr[1];
await chat
.where(userIdsArrayColumn, arrayContains: userIdsArr[0])
.where(userIdsArrayColumn, arrayContains: userIdsArr[1])
.get()
.then((value) {
value.docs.forEach((element) {
docId = element.id;
});
});
return docId;
}
the goal is to get the chat that pertains to the users being passed in userIdsArr

this seems to work, is there a better way of doing this?
Future getChat({required List userIdsArr}) async {
var docId = '';
userIdsArr.sort((a, b) {
return a.compareTo(b);
});
await chat
.where(userIdsArrayColumn, arrayContains: userIdsArr[0])
// .where(userIdsArrayColumn, arrayContains: userIdsArr[1])
.get()
.then((value) {
value.docs.forEach((element) {
if (element[userIdsArrayColumn].contains(userIdsArr[1])) {
log('match found!');
docId = element.id;
}
});
});
return docId;
}

A query can only contain a single array-contains query.
To allow your query, you'll want to add an additional field to the document where you keep the pair of UIDs in a predictable (e.g. alphabetical) order. With such a field you can then use a query such as:
where("concatenated_uids", isEqualTo: userIdsArr[0]+"_"+ userIdsArr[1])

Related

How can i manually add document-fields into local QueryDocumentSnapshot List

i have the following list
List <QueryDocumentSnapshot> globalVideosUrls = [] ;
for example if we use the following
FirebaseFirestore.instance.collection('users')
.limit(1).get().then((value){
globalVideosUrls.add(value)
});
it will add as expected
but what if i want to manually add the following data into globalVideosUrls
document id
00dcb026-3163-4ca0-859e
fields
'videoType':'peace'
'url':'url'
.
globalVideosUrls.add(????)
You have to replace the type "QueryDocumentSnapshot" with QuerySnapshot and then you will get multiple docs and with there data also try this If any questions then ask.
thanks🙏.
List<QuerySnapshot> globalVideosUrls = [];
List<String> videoUrlList = [];
await FirebaseFirestore.instance
.collection('users')
.get()
.then((value) {
globalVideosUrls.add(value);
});
globalVideosUrls.forEach((element) {
element.docs.forEach((docELe) {
print("data:- ${docELe.data()}");
Map map = docELe.data() as Map;
videoUrlList.add(map['url']);
});
});

How to read Firestore field value in flutter?

I want to get field value.
my code is..
void _checkNumner(String number) async {
final userRef = firestore.collection('users');
var documentSnapshot =
await userRef.where("number", isEqualTo: true).get().then((num) {
QuerySnapshot<Map<String, dynamic>> number = num;
print(number);
print("test");
});
print(documentSnapshot);
}
but my console is
how I get field number?
I want to load number values ​​in all docs.
I'm so beginer. T.T
Please reply from the masters
Thank you
Firebase firestore is a NoSQL, document-oriented database. User Data is stored in documents which are organized into collection , i.e collection contains list of document. In simpler words we can say QuerySnapshot contains/provide group of DocumentSnapshot. more about firestore data model
Collection --> QuerySnapshot --> Group of DocumentSnapshot
Document --> DocumentSnapshot
1) Fetch from collection - QuerySnapshot
Here we'll get list of DocumentSnapshots, we can filter by using where commad
Future<void> checkNumber(int number) async {
final QuerySnapshot snapshot = await FirebaseFirestore.instance
.collection('users')
.where("number", isEqualTo: number)
.get();
snapshot.docs.isEmpty
? {
//TODO: your code here
debugPrint("no data found")
}
: {
for (DocumentSnapshot element in snapshot.docs)
{
//TODO: your code here
debugPrint("number is: ${element['number']}"),
debugPrint("name is: ${element['name']}"),
}
};
}
1) Fetch from document - DocumentSnapshot
To fetch data from document we require documentId, and we get a single documentSnapshot instead of multiple like in above way.
Future<void> checkNumberWithDocId() async {
const String docId = 'aaaa';
final DocumentSnapshot snapshot = await FirebaseFirestore.instance.collection('users').doc(docId).get();
snapshot.exists
? {
//TODO: your code here
debugPrint("no data found")
}
: {
//TODO: your code here
debugPrint("number is: ${snapshot['number']}"),
debugPrint("name is: ${snapshot['name']}"),
};
}

Filtering with just one parameter in a list of firestore collection in flutter

I am creating a chat app where people join groups, I have been able to create the groups and allow people to join in, anytime a user joins I save the group object into the user collection, so as to fetch for some other time, now what I want to achieve is fetching all user where group ID is the same value. here is what I have tried.
getUsersInCircle(String circleID) async {
userList.clear();
try {
QuerySnapshot<Map<String, dynamic>> ref = await db
.collection(AppStrings.users)
.where("circles", arrayContains: circleID)
.get()
.then((QuerySnapshot<Map<String, dynamic>> value) {
if (value.docs.isNotEmpty) {
userList.assignAll(
value.docs.map((e) => UserModel.fromJson(e.data())).toList());
print(value.docs.first.data());
} else {
print("no data");
}
return value;
});
return ref;
} catch (e) {
print(e.toString());
}
}
This is what my firestore database looks like
enter image description here
What I want to filter by is the circle Id but it does not return any data
i think i found the problem, you are storing an map inside the circles array, not as a normal array.
this is the difference between an map and array in Firestore
map vs array
Query an array:
where("circles", arrayContains: circleID)
Query an map
where("circles.circleID", isEqualTo: circleID)

How to print values from array field from Firestore?

I have the following courses array in Firestore:
How can I print all the items in Courses array?
I have the following code which currently just fetches the data from Firestore:
printAllValuesFromArray() {
var courses = FirebaseFirestore.instance
.collection('CurrentCourses')
.doc(user.uid)
.get()
.then((value) {
return value['courses'];
});
}
You are correctly fetching the document of the user, all you need is to just print the value like the following:
Future<void> printAllValuesFromArray() {
return FirebaseFirestore.instance
.collection('CurrentCourses')
.doc(user.uid)
.get()
.then((document) {
final courses = document['Courses'];
for (var course in courses) {
print(course);
}
});
}
Note: You were using incorrect key to access the courses from the document which was courses while the correct one is Courses with capital C,
value['courses'].forEach((val) {
print(val);
});
// Can you try this
You can try this,
printallvaluesfromarray() {
var courses = FirebaseFirestore.instance
.collection('CurrentCourses')
.doc(user.uid)
.get()
.then((value) {
print(value.toString())
return value['courses'];
});
}

Flutter - Stream not returning data

I have a document collection called posts_favorites, which stores the reference to all the Posts that a user has bookmarked. The posts_favorites collection look as follows:
I have created a Stream to get all posts references that belong to a specific user, then I want to get the Post documents from the posts collection using the posts references.
I created a Stream to produce the data I need, but I am not getting any data returned from my Stream. Here is my code for the Stream:
Stream<List<PostsRecord>> getFavoritePostsStream() async* {
List<PostsRecord> myList = [];
await FirebaseFirestore.instance
.collection("posts_favorites")
.where("user", isEqualTo: currentUserReference)
.get()
.then((favoriteList) {
favoriteList.docs.forEach((element) async {
String documentPath = element['post'].toString();
var start = documentPath.indexOf("/");
var end = documentPath.indexOf(")");
var documentRef = documentPath.substring(start+1, end);
//DocumentReference docRef = FirebaseFirestore.instance.doc(documentPath);
DocumentReference docRef = FirebaseFirestore.instance.collection('posts').doc(documentRef);
await docRef.get().then((DocumentSnapshot documentSnapshot) async {
if (documentSnapshot.exists) {
print('Document exists on the database');
PostsRecord postsRecord = PostsRecord.getDocumentFromData(
documentSnapshot.data(), element['post']);
//return myList.add(postsRecord);
//print(postsRecord);
return postsRecord;
}
});
});
});
}
I know this function works because the commented code produces the Post Records that I expect to get from Firestore.
I am not sure how to get the Stream function to return data that I can use in the Stream.
Thank you