I am trying to send the data to firebase in my project which I was able to , yet I want the data to override the variable. The one I am using is adding at all the time
setState(() {
velocity = newVelocity;
if (velocity > highestVelocity) {
highestVelocity = velocity;
}
});
future= new Future.delayed(const Duration(seconds: 5));
_firestore.collection('collectionName').add({
'velocity' : velocity
});
}
I think there is update function to override the var. Can I someone help me with that?
To update an existing document, you must know the ID of that document. Once you do, you can update it with:
_firestore.collection('collectionName').doc("theIdOfYourDocument").set({
'velocity' : velocity
});
Also see: how can I set my document id as user uid in cloud fire store?
Related
My current experiment:
I want user to sign in and enter details
When next time he signs in, i want to retrieve his saved information
My intended database structure:
-"users
------"uid"
-----------firstName
-----------lastName`
I use the below code in flutter to create records:
await FirebaseAuth.instance.signInWithEmailAndPassword( email: email, password:
password).then((value)
{
if(value.user.uid != null )
{
final dbRef = FirebaseDatabase.instance.reference().child('users');
dbRef.push().child(user.uid.toString()).set(User().toJson());
}
}
the data gets created with a push key/ID inbetween:
-users
------MFvvXpeRmoQvXkd5VS8 `<---Push ID generated by Firebase`
--------------k8IL4xLQKRf82dxlXNLSHEt2
-----------------------firstName: "sadsadda"
------------------------lastName: "asdsadsad"`
Based on documentations, When i try to retrieve the data using the following code:
final dbRef = FirebaseDatabase.instance.reference().child('users').child(user.uid.toString());
dbRef.equalTo(user.uid.toString()).once().then((snapshot)
{
/*snapshot has value null
}
);
//I even added listener<br>
dbRef.onChildAdded.listen((event) {
readUserInfo(event.snapshot); // even here snapshot value is null.
});
Just for testing purpose, i tried to pass the push key in-between by hardcoding,
final dbRef = FirebaseDatabase.instance.reference().child('users').child('-
MFvvXpeRmoQvXkd5VS8').child(user.uid.toString());`
then "onChildAdded" listener was able to pickup the child entries.
Is this the expected behaviour ? or is there a way to avoid this randomly generated push id?
Thanks for your time in advance
To write the user data under their UID, don't call push(), but simply do:
dbRef.child(user.uid.toString()).set(User().toJson());
To then read the data for the user back, use:
final dbRef = FirebaseDatabase.instance.reference().child('users').child(user.uid.toString());
dbRef.onValue.listen((event) {
readUserInfo(event.snapshot);
});
The .childAdded is needed when you want to read a list of child nodes, for example to read all users:
final dbRef = FirebaseDatabase.instance.reference().child('users');
dbRef.onChildAdded.listen((event) {
readUserInfo(event.snapshot);
});
I'm using below code to retrieve all the data from my firebase chat room
void readDataFromFireBase() {
var databaseReference =
FirebaseDatabase.instance.reference().child("messages");
databaseReference
.child(chatroom.chatId)
.once()
.then((DataSnapshot snapshot) {
Map<dynamic, dynamic> values = snapshot.value;
values.forEach((key, value) {
setState(() {
chatMessageList.add(ChatMessage(
value["message"], value["fromUser"], value["timestamp"]));
chatMessageList.sort((a, b) {
var formatter = new DateFormat('MM/dd/yyyy, kk:mm');
var dateOne = formatter.parse(a.timestamp);
var selectedDate = formatter.parse(b.timestamp);
return dateOne.compareTo(selectedDate);
});
});
});
}
now how can i get notify my chat room when the new message has arrived
currently i'm using below code to listen child added event
listenDataFromFireBase() {
var db = FirebaseDatabase.instance.reference().child("messages");
db.child(chatroom.chatId).onChildAdded.listen((data) {
print("GET_NEW_DATA");
print(data.snapshot.value["message"] ?? '');
print(data.snapshot.value["fromUser"] ?? false);
print(data.snapshot.value["timestamp"] ?? '');
});
}
but there is one issue i'm facing this listenDataFromFireBase() load all the the data from particular room
My requirement is whenever new message added in chatroom i want to animate my message layout
How can i get notify my screen whenever new message will add in my chat room.
If need more information please do let me know. Thanks in advance. Your efforts will be appreciated.
As you've discovered onChildAdded fires immediately for any existing data, and after that also when any data is added. If you want to distinguish between these two cases, you'll need to combine an onChild listener and an onValue listener.
In the onValue listener, all you do is flag whether that event has happened:
databaseReference.onValue.listen((event) {
setState(() {
isInitialDataLoaded = true
});
});
Now do all your data processing in the onChildAdded listener, getting the message from the snapshot and adding it to the list. Then use the isInitialDataLoaded to detect whether this is initial data, or an update:
var db = FirebaseDatabase.instance.reference().child("messages");
db.child(chatroom.chatId).onChildAdded.listen((data) {
// TODO: get message from snapshot and add to list
if (isInitialDataLoaded) {
// TODO: alert the view about the new data
}
});
So you'll have two listeners on the same node. The Firebase SDK actually detects this situation and only reads the data from the server once, so there is no extra data being transferred in this case.
You can use onValue:
/// Fires when the data at this location is updated. `previousChildKey` is null.
Stream<Event> get onValue => _observe(_EventType.value);
But if you use onValue or onChildAdded, it will retrieve all the data under this chatroom.chatId, then when you data is added the onValue event will be fired again and will give you the new data.
Is there a way to retrieve the updated value of a document field updated using firestore.FieldValue.increment without asking for the document?
var countersRef = db.collection('system').doc('counters');
await countersRef.update({
nextOrderCode: firebase.firestore.FieldValue.increment(1)
});
// Get the updated nextOrderCode without asking for the document data?
This is not cost related, but for reliability. For example if I want to create a code that increases for each order, there is no guaranty that if >= 2 orders happen at the same time, will have different codes if I read the incremental value right after the doc update resolves, because if >= 2 writes happen before the first read, then at least 2 docs will have the same code even if the nextOrderCode will have proper advance increment.
Update
Possible now, check other answer.
It's not possible. You will have to read the document after the update if you want to know the value.
If you need to control the value of the number to prevent it from being invalid, you will have to use a transaction instead to make sure that the increment will not write an invalid value. FieldValue.increment() would not be a good choice for this case.
We can do it by using Firestore Transactions, like incremental worked before Field.increment feature:
try {
const orderCodesRef = admin.firestore().doc('system/counters/order/codes');
let orderCode = null;
await admin.firestore().runTransaction(async transaction => {
const orderCodesDoc = await transaction.get(orderCodesRef);
if(!orderCodesDoc.exists) {
throw { reason: 'no-order-codes-doc' };
}
let { next } = orderCodesDoc.data();
orderCode = next++;
transaction.update(orderCodesRef, { next });
});
if(orderCode !== null) {
newOrder.code = orderCode;
const orderRef = await admin.firestore().collection('orders').add(newOrder);
return success({ orderId: orderRef.id });
} else {
return fail('no-order-code-result');
}
} catch(error) {
console.error('commitOrder::ERROR', error);
throw errors.CantWriteDatabase({ error });
}
Had the same question and looks like Firestore Python client
doc_ref.update() returns WriteResult that has transform_results attribute with the updated field value
I'm using react-native-firebase in my app. The problem i'm facing is how to handle the UI updates when user tries to push data when offline.
If the user is online we can use the on() method to get realtime updates but what to do when they are offline. We know that the pushed data is stored in the cache and pushed when user is online again. Can this cached data be used to do what i aim at achieving?
Here's the code i used to receive realtime updates:
var ref333 = firebase.database().ref(`/user-posts/${uid}/`)
ref333.on('value',function (snap) {
var s = snap.val();
console.log("NEW POSTS "+JSON.stringify(s))
})
The code i use to push the data.
var postData = {
uid: uid,
body: 'body',
title: 'title',
starCount: 0
};
// Get a key for a new Post.
var newPostKey = firebase.database().ref().child('posts').push().key;
var ref222 = firebase.database().ref(`/posts/${newPostKey}`)
var ref333 = firebase.database().ref(`/user-posts/${uid}/${newPostKey}`)
ref222.push(postData, function (onComplete) {
console.log("COMPLETED")
ref333.push(postData,function (onComplete) {
console.log("NEXT COMPLETED")
}, function (error) {
console.log("ERROR IN ",error)
})
}, function (error) {
console.log("error == "+error)
})
The .on snspashot listener should be triggered even if in offline mode.
According to the docs:
https://firebase.google.com/docs/database/web/read-and-write
You can use the value event to read a static snapshot of the contents
at a given path, as they existed at the time of the event. This method
is triggered once when the listener is attached and again every time
the data, including children, changes.
This should work in offline mode as well. If you are not receiving updates - something else is wrong.
This problem was solved by adding this lines of code to your native code:
https://rnfirebase.io/docs/v5.x.x/core/default-app#Enable-Database-Persistence
I am creating a chat listing with react native and firebase. My firebase database is like this.
I am able to list the chats but it is not updating when a new chat adds or when I send a new message in old chat. My code is like this.
// find chat tread ids for a user.
firebase.database().ref('user/64/threads')
.on('value').then(snapshot => {
// find chat thread details for a id
const chatIds = snapshot.val();
for (let chatId of chatIds.keys()) {
firebase.database().ref('threads/'+chatId).once('value')
.then(snapshot1 => {
// find members from snapshot.val().members
// find id of other users.
if (chatId.split('-')[0] == '64') {
// find name of chatId.split('-')[1]
} else {
// find name of chatId.split('-')[0]
}
})
}
});
I am stuck in this forever. I am able to fetch chat listing one time but I am not getting whenever a new chat is added or when a new message is added in existing chat. Please help.