Closed jakelowen closed 7 years ago
Hi @jakelowen
Firebase
takes care of it for us :)
From the docs:
The
value
event is used to read a static snapshot of the contents at a given database path, as they existed at the time of the read event. It is triggered once with the initial data and again every time the data changes.
The implementation in firebase-list.js
is just an example to show how you can use the value
callback to wait until the initial data has loaded.
Depending on your needs, you might choose not to use value
in this way, and instead rely solely on child_added
(or vice versa).
Thanks @r-park - Thank you, I think I'm with you.
In this code snippet (directly from firebase-list.js)
ref.once('value', () => {
initialized = true;
emit(this._actions.onLoad(list));
});
ref.on('child_added', snapshot => {
if (initialized) {
emit(this._actions.onAdd(this.unwrapSnapshot(snapshot)));
}
else {
list.push(this.unwrapSnapshot(snapshot));
}
});
Are both ref.once('value'....
AND ref.on('child_added'..
both separate database reads that are happening simultaneously? So if there are 3 children at that path, I am actually downloading the 3 children twice (total of 6 records), but because .once
is not reading the snapshot it is essentially throwing away the data collected and thus only being used as a timer mechanism to emit the list (presumably after the .on('child_added')
is also done populating the list?
Could I theoretically avoid the ref.once('value'....
call altogether by expanding the ref.on('child_added'..
section to something like: (pseudocode, untested):
ref.on('child_added', snapshot => {
if (initialized) {
emit(this._actions.onAdd(this.unwrapSnapshot(snapshot)))
} else {
initialized = true;
emit(this._actions.onLoad(this.unwrapSnapshot(snapshot)))
}
})
Or is the ref.once('value'....
playing some special role that I am failing to grasp?
Oh, I see. My above rewritten code only grabs the first item from child_added into onLoad. All subsequent children on initial read are put into onAdd. So I need a way to wait for all children before I dispatch to onLoad. That must be what your .once
function was doing.
If you're only going to use child_added
, the initialized
flag is probably unnecessary, unless you want to know when the first item has been loaded.
You can simplify it to something like this:
//let initialized = false;
//let list = [];
/*
ref.once('value', () => {
initialized = true;
emit(this._actions.onLoad(list));
});
*/
ref.on('child_added', snapshot => {
emit(this._actions.onAdd(this.unwrapSnapshot(snapshot)));
}
Keep in mind that this._actions.onAdd()
will trigger a view update each time it's fired.
That must be what your
.once
function was doing.
👍
Thank you @r-park - I follow now. Kudos on an extremely well written code example. I don't think I could have cracked firebase with redux had it not been for you.
For future reference to other future searchers.., this SO question addresses why this approach of both a .once
and a .on('child_added')
work well together: http://stackoverflow.com/questions/27978078/how-to-separate-initial-data-load-from-incremental-children-with-firebase?noredirect=1&lq=1
Hope you don't mind me asking via this means, but I have a very quick question about the firebase-list.js class used in https://github.com/r-park/todo-react-redux/blob/master/src/core/firebase/firebase-list.js
I've spent hours studying this code and inserting lots of console logs to track the flow / sequence of events.. I can not wrap my mind around how
ref.once
function one line 52 is working.How do you get it to wait until the all the
ref.on('child_added'
events occur before the.once
function emits the list?I don't see any explicit sequencing here, so I can not figure it out. It appears that events happen in this order:
.on('value')
function fires.. and loads all the items from the ref into the list..once
function then sets initialized to true and emits the list.How in the world is the .once function waiting until all the
.on('value')
process is complete? And do I read this correctly that the.once()
is not actually utilizing the data it grabs because there is no snapshot being passed to the callback / no unwrapping?Can anyone help me understand?