I am very new to flutter and firebase and am really struggling.
I have been trying for about 2 weeks to work this out but I can't for the life of me work out what I am doing wrong.
I am trying to retrieve the 'DisplayName' from a 'users' collection with UID Document and DisplayName.
When I use The MyUser in other widgets using the provider package the DisplayName displays null, the console displays ' not again' so it appears that it's just not working at this point.(code below)
I have researched and I can't seem to find any why this code works. I am a NOOB so it may be something simple and after 2 weeks I thought I would ask for help.
Thanks In advance anything I can learn would be great.
Stream<List<MyUser>> get user {
var user = FirebaseFirestore.instance.collection('users');
return user.snapshots().map((list) => list.docs
.map((doc) => MyUser(
displayName: doc['DisplayName'] ?? 'not again',
))
.toList());
}
Related
I am creating an application using Firebase Firestore and Plugin.CloudFirestore for Xamarin Forms based off of the Sample Project posted on the plugin's GitHub (link:
https://github.com/f-miyu/Plugin.CloudFirestore).
I am trying to learn how to write Async Reactive Commands based off of how they are written in the sample project but I'm having a really hard time reverse engineering this code.
UpdateCommand = new[] {
_todoItem.Select(x => x == null),
Name.Select(x => string.IsNullOrEmpty(x))
}.CombineLatestValuesAreAllFalse()
.ObserveOn(SynchronizationContext.Current)
.ToAsyncReactiveCommand();
UpdateCommand.Subscribe(async () =>
{
var todoItem = _todoItem.Value;
todoItem.Name = Name.Value;
todoItem.Notes = Notes.Value;
_ = CrossCloudFirestore.Current.Instance.Document($"{TodoItem.CollectionPath}/{todoItem.Id}")
.UpdateAsync(todoItem)
.ContinueWith(t =>
{
System.Diagnostics.Debug.WriteLine(t.Exception);
}, TaskContinuationOptions.OnlyOnFaulted);
await navigationService.GoBackAsync();
});
This code snippet is from the "TodoItemDetailPageViewModel.cs" file within the sample project if you would like more context.
The code above updates the field values of the document that is selected from the main page via the Firestore API. The code is working but I don't have any idea what the above code means and how the command works. Could someone break it down for me and explain what is going on? I am sure someone else could benefit as well.
Thanks
I'm trying to create a Blocked Users list in my chat app using the latest versions of Flutter Beta channel (1.23.0-18.1.pre) and cloud_firestore 0.14.3.
Here's my data structure:
At first, I tried something like this (Hardcoded just to test), by filtering the messages I'm querying from Firestore. Firebase doesn't like this.
query: firestore.collection('messages')
.where('userId', whereNotIn: ['123456789', '987654321'] )
.where('hashtag', isEqualTo: hashTag)
.orderBy('submittedAt', descending: true),
reverse: true,
I get this error:
E/FLTFirestoreMsgCodec(24331): java.lang.IllegalArgumentException: Invalid query. You have an inequality where filter (whereLessThan(), whereGreaterThan(), etc.) on field 'userId' and so you must also have 'userId' as your first orderBy() field, but your first orderBy() is currently on field 'submittedAt' instead.
After doing some more reading, filtering on the client-side by just hiding the messages actually better suits my needs.
Unfortunately, I'm running in circles. I'm currently thinking I would map a stream to a list, and then do something like this:
if (message.userId is in the list) {
isBlocked = true;
} else {
isBlocked = false;
}
And then filtering out the messages if isBlocked is true. I tried hardcoding the values for that and it worked. BTW, Sorry for the pseudocode, but I deviated so many times that now I'm simply lost.
I was wondering if this was the correct approach? Any suggestions would be rad. I also tried using a future list from a stream but I couldn't get that to work either.
Future<Stream<List<BlockedUser>>> getBlockedIds() async {
Stream<List<BlockedUser>> list;
Stream<QuerySnapshot> snapshot = FirebaseFirestore.instance.collection('user').doc('id').collection('blocked').snapshots();
list = snapshot.map((query) => query.docs.map(
(doc) => BlockedUser(
id: doc.data()['id'])
).toList());
return list;
}
I can't get that to work since I don't know what to do with that list.
Thanks, everyone!
I have cloud fire store object like this
"TestCollection" : ["Test1","Test"]
Now I want to update this array with FieldValue.arrayUnion
because if element is same then i don't want to do anything but if it is not then I would like to add element
docRef.updateData({"TestCollection":FieldValue.arrayUnion(["test"])})
but this statement gives the error like object can not have nested array
Can anyone please help or provide same kind of example to have look for syntax ?
I have found a solution.
Try this:
Firestore.instance
.collection('YourCollection')
.document('YourDocument')
.updateData({'array':FieldValue.arrayUnion(['data1','data2','data3'])});
If it still doesn't work, try to update your Firebase.
First open a terminal fetched to your flutter project, then:
cd ios
pod update Firebase
This solution is only for mac users.
New FlutterFire Update 2021
With the newest FlutterFire update there where lots of updates at the API but thankfully it hasn't changed that much for this problem. I'm talking about the newest plugins of Firebase for Flutter and specifically every plugin that is compatible with the new firebase_core ^0.7.0.
So the code looks similar:
FirebaseFirestore.instance
.collection("YourCollection")
.doc("YourDocument")
.update({
"anArray": FieldValue.arrayUnion(["data", "to", "append"])
});
The other way if you have List of objects
Future<void> updateUserNewGroup(List<Group> data , String id) {
List<Map> list=new List();
if(data !=null && data.isNotEmpty){
data.forEach((grp){
list.add(grp.toJson());
});
}
return ref.document(id).updateData({"groups": FieldValue.arrayUnion(list)}) ;
}
Following up on the existing answers, if the field does not exist you can use a set & merge. This can save you from checking if the field exists or not.
Firestore.instance
.collection('YourCollection')
.document('YourDocument')
.setData({
'array':FieldValue.arrayUnion(['data1','data2','data3'])
}, merge: true);
this is the code I used and it worked like a charm!
_firestore
.collection('x')
.document('xxxxxxxxxx')
.updateData({
'comments': FieldValue.arrayUnion([
{'comment': "comment goes here", 'sender': "xxxxxxxx#gmail.com"}
])
});
2023
Use .set() with SetOptions(merge: true)
await FirebaseFirestore.instance.collection('users').doc(userService.userId).set({
'lastLogin': FieldValue.serverTimestamp(),
'devices': FieldValue.arrayUnion([removeSpaces(deviceId)]),
}, SetOptions(merge: true));
Disclaimer, I am trying to self-teach myself development. I am building a hybrid mobile app using Ionic 1 and now Firebase 3 for my database and authentication.
For my scenario, in short, I'm trying to display a list of 'friends' for the user that is currently logged in. Here is the current data structure I have (the relevant part anyway):
Data Structure
I have a line of code that does return me what I want:
var friends = $firebaseArray(ref.child('users').child('-KXcxMXkKs46Xv4-JUgW').child('friends'));
Of course, that can't work because there is a nice little hard coded value in there.
So, I looked into how to retrieve the current UID so I could replace the hard coded value. But after running the following bit of code through, the first node under user is not the UID (it is some other auto generated value that I don't really know how it got there). The UID is actually within the id field.
var ref = firebase.database().ref();
authObj = $firebaseAuth();
var firebaseUser = authObj.$getAuth();
console.log(firebaseUser.uid);
So, ultimately what I would love is to be able to change the data structure so that the UID is the first node under Users, but I can't seem to find documentation to do that. I looked at this other stack thread, but it is for an outdated version and I can't seem to connect the dots. Other thread
Though, if I can't change the structure, I still need to figure out how to access that friends node for the current user, one way or another.
Thank you in advance. This is my first stackoverflow post, so be gentle.
Update:
Per Frank's comment, this is the code that I execute to create users - $add is what is creating the push id (-KXcxM...).
createProfile: function(uid, user) {
var profile = {
id: uid,
email: user.email,
registered_in: Date()
// a number of other things
};
var messagesRef = $firebaseArray(firebase.database().ref().child("users"));
messagesRef.$add(profile);
},
register: function(user) {
return auth.$createUserWithEmailAndPassword(user.email, user.password)
.then(function(firebaseUser) {
console.log("User created with uid: " + firebaseUser.uid);
Auth.createProfile(firebaseUser.uid, user);
Utils.alertshow("Success!","Your user has been registered.");
})
.catch(function(error) {
Utils.alertshow("Error.","Some helpful error message.");
console.log("Error: " + error);
});
}
Instead of creating a $firebaseArray and calling $add on it, you can just store the user using the regular Firebase JavaScript SDK:
createProfile: function(uid, user) {
var profile = {
id: uid,
email: user.email
};
firebase.database().ref().child("users").child(uid).set(profile);
}
Since AngularFire is built on top of the Firebase JavaScript SDK, the two interact nicely with each other. So if you have any existing $firebaseArray on users it will pick up the new profile too.
Using the motion-firebase library for RubyMotion Firebase (https://github.com/colinta/motion-firebase) I can set data easy enough either by doing:
firebase.set({ full_name: ['first_name' => 'Fred', 'last_name' => 'Flintstone'] })
or
firebase['first_name'] = 'Fred'
But I'm having trouble figuring out how to retrieve data.
I've tried the different firebase.query methods listed in the reponse readme but I'm definitely missing something.
I'd hoped it would be as simple as:
firebase.query['first_name']
=> 'Fred'
Could someone please explain how I might go about querying Firebase with a key and returning the value.
colinta here! You'll need to attach an observer (https://github.com/colinta/motion-firebase#attaching-observers-to-read-data).
firebase_ref.once(:value) { |snapshot| snapshot.value }
See https://www.firebase.com/docs/ios-api/Classes/FDataSnapshot.html for info on the FDataSnapshot type.