I've been working with Flutter and Firebase lately, I'm facing a confusing problem today and would like some help.
I have a Collection in Firebase Cloud Firestore that contains Documents which their names are quite long.
The photo below shows them:
I wrote a function in Dart to check the existence of a specific document, it's also pretty simple:
Future<String> checkForExistance(String mnemonic) async {
final String seedHex = bip39.mnemonicToSeedHex(mnemonic);
final snapShot = await FirebaseFirestore.instance
.collection('wallets')
.doc(seedHex)
.get();
if (!snapShot.exists) {
if (kDebugMode) {
print('SnapShot not exist');
}
return 'NO_IDEA';
} else {
if (kDebugMode) {
print('Snapshot Exist');
}
return seedHex;
}
}
The return result is always 'SnapShot not exist'.
The return is always 'SnapShot not exist' even though I've made sure I'm checking for the existence of exactly what I need.
Even when I hard coded the name of one of those documents, the result is 'SnapShot not exist' (this is what confuses me).
Future<String> checkForExistance(String mnemonic) async {
final String seedHex = bip39.mnemonicToSeedHex(mnemonic);
final snapShot = await FirebaseFirestore.instance
.collection('wallets')
.doc(**'hard coded'**)
.get();
if (!snapShot.exists) {
if (kDebugMode) {
print('SnapShot not exist');
}
return 'NO_IDEA';
} else {
if (kDebugMode) {
print('Snapshot Exist');
}
return seedHex;
}
}
So I tried creating a document with a shorter name (the 's' at the end of the image) and hard coded it, the results returned as expected which is 'Snapshot Exist'.
Is it because my documents name is too long that Firebase search is not working as expected?
Thanks for everyone's help.
From what I can see in the screenshot the document names are shown in italic, which means that there is no document with that name and the console merely shows it because there are subcollections under that path.
That also explains why you can't load those documents through the API, there are no documents to load.
You will either already have to know of the existence of these paths, or you can load the documents from the subcollections with a collection group query and then determine the parent path(s) from that.
Related
I'm quite new to flutter and dart. I have started to build an app to help understand the languages better. So far I can authenticate users, log them in, log them out and perform actions based on the status of the user etc.... but I have been struggling for hours on something that I imagine is quite a basic concept. I have tried countless code examples from SO and Flutter Dev but nothing seems to work.
I want to query my Cloud Firestore, searching for any documents that have the document name of 'uid' that matches the current logged in users user ID. This code brings me no errors in Android Studio, and the app runs fine and displays the 'page' but does not redirect or print anything.
As this is really just saying if it's empty do x but if it's not empty do y - even if the syntax was wrong (even though AndroidStuid says it's valid) I would still expect it to change the path to either 'Home' or 'Hometwo' and print one of the two statements, but it does nothing.
If I simply print 'user' it does this ok, and displays the current users ID - but seems to 'break' when querying the collection?
What am I doing wrong here?
void checkCurrentUser() async {
// final FirebaseFirestore database = FirebaseFirestore.instance;
final user = await _auth.currentUser.uid;
if (user == null) {
navigateToSubPageMyAccount(context);
} else {
FirebaseFirestore.instance
.collection('samplecollection')
.doc(user)
.get()
.then((DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists) {
navigateToSubPageHome(context);
print('Document exists on the database: ${documentSnapshot.data()}');
} else {
navigateToSubPageHomeTwo(context);
print('Document does not exist');
}
});
}
}
Update:
I found the answer as per my comment below. If anyone else stumbles upon this thread, the reason none of this code was working is because I had commented it out in error from within initState during some other testing:
void initState() {
super.initState();
// checkCurrentUser();
}
...and simply removed the commenting so it was included when the app ran:
void initState() {
super.initState();
checkCurrentUser();
}
How many read in firebase if under one await I run a loop and I have 20 documents in total but my loop will filter out some after checking. After checking it will take 10 data. But for taking, it needs to read 20 documents. So how many read will it count? I heard one await one read. But my firebase dashboard is showing 5/6 times more. In the picture i have shown the code.
please tell me how many read will it count?
Future getUser() async {
final id = await FirebaseAuth.instance.currentUser();
userId=id.uid;
await Firestore.instance.collection('user').getDocuments().then((users) {
print("loop running");
for (var user in users.documents) {
if ((!seenList1.contains(user.documentID)) &&
(!chosenList1.contains(user.documentID)) &&
(!showId1.contains(user.documentID)) &&
(user.documentID != userId) &&
("male" == user['gender'])
) {
loc(user['Location'].latitude, user['Location'].longitude).then((result){
if(result==true){
setState(() {
showId1.add(user.documentID) ;
showName1.add(user['name']) ; }
});
}
}
});
return ;
}
The call to getDocuments() determines how many documents are read. So in your case:
Firestore.instance.collection('user').getDocuments()
This means that all documents from the user collection are read. If those documents are not in the local cache of the device yet, Firestore will have to read them on the server and return them to the client.
So say your cache is empty: that'd mean that you're charged a read for each document in the user collection, and the total bandwidth that is used for downloading those documents.
This is my Firestore setup. As you can see, there are documents in this collection.
This is my code to get a Snapshot of the documents in the collection. It is always returning false. Can someone help me figure out how to fix it?
firebase.firestore().collection("chatMessages").doc("chatMessages").collection(chatId).get()
.then((snapshot) => {
if (snapshot.exists) { // <- always returning false
console.log("snapshot exists");
}
})
}
For a query there is no .exists property -- that's a property of a DocumentSnapshot not a QuerySnapshot. I think you want empty instead:
if (!snapshot.empty) {
console.log('query returned results');
}
Refer this for more details - https://firebase.google.com/docs/firestore/query-data/get-data
I am trying to do something along the lines that, if there does not exist a document then do setData and if the document exist, do update data... I have tried this(the code below), it seems to work but I am concerned that what if when I launch the app and the error message changes.
Future updateReference(
String phoneNumber,
) async {
try {
return await mCollectionRef.document(phoneNumber).updateData({
uid: true,
});
} on PlatformException catch (error) {
print(error.message.substring(0, 9));
if (error.message.substring(0, 9) == 'NOT_FOUND') {
return await mCollectionRef.document(phoneNumber).setData({
uid: true,
});
}
}
}
Is there any other way in which I can achieve this?
If you want to update or create a document if it doesn't already exist, you can just pass merge: true as the second argument to setData().
So basically I have a collection a User and within each user there is a subcollection for the pending friend request that the user have, something like that:
/users/[auto-id]/friend_requests/[auto-id]/{user: ref to another user}
But one user can obviously have multiple requests at the same time and I have an hard time to get the data correctly.
What I'm correctly trying to do is to get a list of user that are in the subcollection "friend_requests":
_loadFriendRequests() async {
try {
this._users.addAll(await _dataService.fetchFriend());
} catch (e, stackTrace) {
printException(e, stackTrace, "Error loading friends");
}
}
And in dataService:
Future<List<User>> fetchFriend() async {
final querySnapshot =
await _currentUserDoc.reference.collection("friend_requests").getDocuments();
return await Future.wait(querySnapshot.documents.map((doc) async {
final user = await doc["user"].get();
User(
id: user["id"],
name: user["name"],
);
}).toList(growable: false));
}
This is just the last thing that I tried but I tried in so many ways, with Future.wait() too, with/without async/await, etc
I just can't seem to make it work...
You're missing a return statement after final user = await doc["user"].get();
This could become a lot easier if you use Streams or fancy rxdart