I am using fire store with angular and used onsnapshot method. To remove the listener I did the similar way what docs is suggesting but still I am receiving the real time updates. Any suggestions?
unsubscribe:any;
this.unsubscribe = db.collection("cities")
.onSnapshot(function (){
// Respond to data
});
this.unsubscribe();
Related
I'm having some trouble on understanding the unsubscribe() function usage for detaching listeners.
I'd like detach listener every time that user click button show table for changing view options.
Actually this is my code.
Previously query was called unsubscribe as reported in the official Firestore documentation (I also tested the same example code from documentation in my project) and in console log always return unsubscribe is not a function
let query;
$(".btnShowTable").on("click", function () {
if(typeof query != "undefined") query.unsubscribe();
createTable(param);
});
function createTable(param) {
query = db.collection("test1/test2/"+param).orderBy("dataora", "desc").limit(10);
query.onSnapshot(function (querySnapshot) {
querySnapshot.docChanges().forEach(function (change) {
// get datas
});
});
}
What should I change in my code?
query is a Query type object, and you can see from the API documentation that it doesn't have an unsubscribe() function. What you'll need to do is follow the instructions in the documentation. It says that onSnapshot() returns an unsubscribe function to call when it's time to unsubscribe.
// subscribe to query results
const unsubscribe = query.onSnapshot(...)
// later, unsubscribe the listener
unsubscribe()
I'm using mobx-state-tree's onSnapshot() feature to listen to state changes, I then persist the state with every change in local storage. This is how I do it:
import { onSnapshot } from "mobx-state-tree";
onSnapshot(store, newSnapshot => {
saveLocalSnapshot(newSnapshot);
});
My question is, how do I unsubscribe from onSnapshot() when my app needs to stop persisting every snapshot?
Helper functions like onSpanshot or onPatch (and basically every other subscribe method) return IDisposer, which is basically a function that you can call to literally dispose the subscription.
Is there any event to listen data on every update whether it is exactly the same data or not?
Let me explain what I want to achieve.
If I set the data as shown below on every 1 second interval
Write Data
setInterval(() => {
firebaseRef.child('liveUser').set({ userId: 1});
}, 1000);
How can I listen liveUser on every update? Right now with my current implementation firebase stop .on('value') event if the value is duplicate.
Read Data
firebaseRef.child('liveUser').on('value', (snapshot) => {
console.log(snapshot.val());
})
I am aware of alternative solution of using timestamp with liveUser object, but it would be helpful if firebase already provides solution for duplicate data.
By design, a listener is only called when data is changed. Writing identical data to the same location does not change the data and thus doesn't trigger attached listeners.
To trigger attached listeners, you need to make a change to the node:
setInterval(() => {
firebaseRef.child('liveUser').set({
userId: 1,
timestamp: Math.floor(Date.now())
});
}, 1000);
I try to get all 10 records using this:
exports.checkchanges = functions.database.ref('school/{class}').onCreate(snap => {
const class=snap.params.class;
var ref = admin.database().ref('/students')
return ref.orderByChild(class).startAt('-').on("child_added", function(snapshot) {
const age=snapshot.child("age");
// do the thing
})
)}
The problem is that after I get the 10 records I need correctly, even after few days when a new record is added meeting those terms, this function is still invoked.
When I change on("child_added to once("child_added I get only 1 record instead of 10. And when I change on("child_added to on("value I get null on this:
const age=snapshot.child("age");
So how can I prevent the function from being invoked for future changes?
When you implement database interactions in Cloud Functions, it is important to have a deterministic end condition. Otherwise the Cloud Functions environment doesn't know when your code is done, and it may either kill it too soon, or keep it running (and thus billing you) longer than is necessary.
The problem with your code is that you attach a listener with on and then never remove it. In addition (since on() doesn't return a promise), Cloud Functions doesn't know that you're done. The result is that your on() listener may live indefinitely.
That's why in most Cloud Functions that use the Realtime Database, you'll see them using once(). To get all children with a once(), we'll listen for the value event:
exports.checkchanges = functions.database.ref('school/{class}').onCreate(snap => {
const class=snap.params.class;
var ref = admin.database().ref('/students')
return ref.orderByChild(class).startAt('-').limitToFirst(10).once("value", function(snapshot) {
snapshot.forEach(function(child) {
const age=child.child("age");
// do the thing
});
})
)}
I added a limitToFirst(10), since you indicated that you only need 10 children.
I have a large data set (~100k entries), that is being subscribed to using the 'child_added' event. Using node 7 and firebase 3.6.1, doing this seems to download the entire 100k entries before a single child_added event is fired.
Memory consumption grows significantly for a few dozen seconds, and then all child_added events are fired swiftly after each other.
This is slow:
require('firebase').
initializeApp({databaseURL: 'https://someproject.firebaseio.com'}).
database().ref('data').
on('child_added', (snap) => console.log(snap.key));
Limiting is still fast (few seconds delay):
require('firebase').
initializeApp({databaseURL: 'https://someproject.firebaseio.com'}).
database().ref('data').limitToFirst(10).
on('child_added', (snap) => console.log(snap.key));
Given the streaming nature of Firebase, I assume it is not intended behaviour for child_added subscriptions to download the entire data set to the client before anything is done.
Am I doing something wrong, or is this a bug?
Although that in the child_added section extracted from firebase documentation it says:
The child_added event is typically used when retrieving a list of items from the database. Unlike value which returns the entire contents of the location, child_added is triggered once for each existing child and then again every time a new child is added to the specified path. The event callback is passed a snapshot containing the new child's data. For ordering purposes, it is also passed a second argument containing the key of the previous child.
At the first lines in that page, we can found this:
Data stored in a Firebase Realtime Database is retrieved by attaching an asynchronous listener to a database reference. The listener will be triggered once for the initial state of the data and again anytime the data changes.
Seems to be its normal behaviour. It first retrieves all the data.
I am in the same situation, waiting nearly 40 seconds for the first child to fire. The only solution I could come up with was to get the keys using Firebase rest API and shallow query parameter, then loop over each key and call Firebase. Here is basically what I did.
`
console.log('start', Date.now());
fetch('https://[firebase_app].firebaseio.com/[your_path].json?shallow=true')
.then((response) => {
return response.json();
}).then(function(j) {
Object.keys(j).forEach(function (key) {
console.log(key, 'start', Date.now());
firebase_reference.child(key).on("child_added", function (snapshot) {
console.log(key, Date.now());
//now you have the first response without waiting for everything.
});
});
});`
I know this doesn't answer your question about child_added functionality, but it does what you would expect to happen with child_added. I am going to submit a feature request to Firebase and link this SO question.