Is it supposed to be any difference on running this two codes?
ref.on('child_added',function(child,prev){
console.log(child.key+prev);
}
ref.off();
and
ref.once('child_added',function(child,prev){
console.log(child.key+prev);
}
I've been surprised that the second one doesn't iterates between the childs!
What am I doing wrong here (edited->)to obtain a complete list of the childs?
When you use once, you're asking for a single event of the indicated type. So once("child_added" fires a single child_added event.
The fact that your on fires multiple times, is likely a race condition because of the way you ordered the calls. I'd expect this to also invoke only once:
ref.on('child_added',function(child,prev){
console.log(child.key+prev);
ref.off();
}
But I must admit this is pretty uncommon, so I don't think I ever tested it.
In addition to #Puf's answer I would add this quote from documentation you should be aware:
Add queries to limit the data that your listen operations return and
use listeners that only download updates to data — for example, on()
instead of once(). Reserve .once() for actions that truly don’t
require data updates.
Source: https://firebase.google.com/docs/database/usage/optimize
Another usefull link: https://firebase.google.com/docs/database/usage/billing
Related
how can i start Flux after completion of Flux? Flux doesn't depend on result of Flux.
I thought operation then() should do the work, but it just return mono. So what is the correct operator?
Flux.thenMany is the operator that you need
abstract Flux<Integer> flux1();
abstract Flux<String> flux2();
public Flux<String> flux2AfterFlux1(){
return flux1().thenMany(flux2());
}
My reply is late, so you have probably either figured this out, or moved on. I need to do the same thing, so I seem to have achieved this by using Flux.usingWhen(). I need to obtain IDs from my database that exhibit a certain property. After retrieving these IDs, then I need to get some information about these IDs. Normally, a join would work, but I am using MongoDB, and joins are horrible, so it is better to do separate, sequential queries. So let's say I have a Mongo reactive repository with a method called Flux<String> findInterestingIds(). I have another method in the same repository called Flux<String> findInterestingInformation(String[] interestingIds) that I need to feed the IDs found in the call to the previous method. So this is how I handle it:
Mono<List<String>> interestingIdsMono = myRepo.findInterestingIds()
.collectList();
Flux.usingWhen(interestingIdsMono,
interestingIds -> myRepo.findInterestingInformation(interestingIds),
interestingIds -> Flux.empty().doOnComplete(() -> log.debug("Complete"));
The cleanup function (third parameter) was something that I don't quite yet understand how to use in a good way, so I just logged completion and I do not need to emit anything extra when the flux completes.
ProjectReactor used to have a compose function that is now called transformDeferred, and I had some hopes for that, but I do not quite see how it would apply in this type of situation. At any rate, this is my attempt at it, so feel free to show me a better way!
When writing event based cloud functions for firebase firestore it's common to update fields in the affected document, for example:
When a document of users collection is updated a function will trigger, let's say we want to determine the user info state and we have a completeInfo: boolean property, the function will have to perform another update so that the trigger will fire again, if we don't use a flag like needsUpdate: boolean to determine if excecuting the function we will have an infinite loop.
Is there any other way to approach this behavior? Or the situation is a consequence of how the database is designed? How could we avoid ending up in such scenario?
I have a few common approaches to Cloud Functions that transform the data:
Write the transformed data to a different document than the one that triggers the Cloud Function. This is by far the easier approach, since there is no additional code needed - and thus I can't make any mistakes in it. It also means there is no additional trigger, so you're not paying for that extra invocation.
Use granular triggers to ensure my Cloud Function only gets called when it needs to actually do some work. For example, many of my functions only need to run when the document gets created, so by using an onCreate trigger I ensure my code only gets run once, even if it then ends up updating the newly created document.
Write the transformed data into the existing document. In that case I make sure to have the checks for whether the transformation is needed in place before I write the actual code for the transformation. I prefer to not add flag fields, but use the existing data for this check.
A recent example is where I update an amount in a document, which then needs to be fanned out to all users:
exports.fanoutAmount = functions.firestore.document('users/{uid}').onWrite((change, context) => {
let old_amount = change.before && change.before.data() && change.before.data().amount ? change.before.data().amount : 0;
let new_amount = change.after.data().amount;
if (old_amount !== new_amount) {
// TODO: fan out to all documents in the collection
}
});
You need to take care to avoid writing a function that triggers itself infinitely. This is not something that Cloud Functions can do for you. Typically you do this by checking within your function if the work was previously done for the document that was modified in a previous invocation. There are several ways to do this, and you will have to implement something that meets your specific use case.
I would take this approach from an execution time perspective, this means that the function for each document will be run twice. Each time when the document is triggered, a field lastUpdate would be there with a timestamp and the function only updates the document if the time is older than my time - eg 10 seconds.
I'm implementing drag/drop behavior in my model, which is derived from QAbstractItemModel. My code (C++) for the drop event looks something like this:
beginInsertRows(destination_index, row, row);
destination->AcquireDroppedComponent(component);
endInsertRows();
The call to AcquireDroppedComponent can fail for a number of reasons and reject the drop, in which case no new rows will be inserted in the index stored in destination_index. My question is will calling begin/endInsertRows cause problems if this happens? My limited testing on Windows 7 so far shows no undesirable behavior, but I want to be thorough and not rely on the specific behavior of one platform. I can check beforehand if the drop will succeed or not, but I'd like to avoid the extra code if I can. My question also applies for the other begin/end functions like beginRemoveRows, beginInsertColumns, etc.
Calling these methods without doing the actions you indicate breaks their contract. How the clients of your model will cope with that is essentially undefined.
I can check beforehand if the drop will succeed or not, but I'd like to avoid the extra code if I can.
That "extra" code is absolutely necessary.
I'd refactor your code to perform acquisition and model change separately:
if (destination->acquireDroppedComponent(component)) {
beginInsertRows(destination_index, row, row);
destination->insertDroppedComponent(component);
endInsertRows();
}
The acquireDroppedComponent would store the data of the dropped object without modifying the model, and return true if it was successful and the data is usable. You then would call insertDroppedComponent to perform the model change.
I am working with a pretty complicated .aspx page that is full of controls (Telerik, Ajax, etc.) that all expand, collapse, show, hide, etc. when the page is loaded. Since this rendering happens on the client-side and can take different lengths of time based on the users machine specs, is there a way to detect when all (or some) rendering has taken place (jQuery?) so I can then act on specific elements, knowing they are fully rendered?
JavaScript is single threaded. The time passed to setTimeout is a minimum, but not a maximum, so if you pass something like 10(ms), you essentially are saying "execute this code after all the currently running code is finished."
So, if all the controls use $(document).ready() to do their thing, all you need is:
$(document).ready(function() {
setTimeout(function() {
doStuff();
},10);
});
doStuff will be called after all the functions passed to $(document).ready have run. However, this isn't foolproof. If the controls have their own way of detecting whether the document has loaded, or do their own setTimeout(), you're in trouble. The problem is that JavaScript does not guarantee the execution order of setTimeouts. Sometimes your code may run last, other times it may run before the setTimeouts used for the animation.
One last idea: if all the animation is done using jQuery, then the effects run in a single queue. In doStuff you could add an animation of some sort with a callback and be reasonably certain that the callback would run last.
Whenever I had to wait for multiple things to be ready before proceeding, I would create an array with true/false values. Every mandatory part of the page got an event which, when it is called, updates the specific entry in the array to true. Also, it called a general function which returned true if all values in an array was true, otherwise false.
If that function finally returned true, I would proceed with the execution. It is especially useful if you have to wait for an AJAX call to end but don't want to use async = true. It also is useful if you want to start loading multiple things at once instead of one after another, since they all report ready-state to the same array.
It does however use global variables so you might need to do some optimizations. You might not want to do this approach either if you have a grudge against global variables.
You should place your code inside the jQuery $(document).ready() function. This will ensure that all elements are loaded before the code runs.
http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
I think the doc you need is:
http://docs.jquery.com/Events/load
"I can then act on specific elements, knowing they are fully rendered?"
You can use the load method (linked above) to attach to any element. So if you had a div with an id of "lastElement", you could write
$('div#lastElement).load(runThisFunction);
Is there a way to make synchronous calls using RemoteObject in Flex?
All IO in Flex is asynchronous. The typical pattern to deal with this is to use an AsyncResponder. For instance:
var t:AsyncToken = remoteObject.methodCall();
t.addResponder(new AsyncResponder(resultEvent, faultEvent));
think twice when u want it to be synchronous.
Do u know what synchronous mean? it will FREEZE your application until it receive data. Unless u are pretty sure that your remote calling can receive return value immediately (super fast network connection).
if your function call depends on each other, i would suggest you implement a state machine. e.g.
after 1st async call, your state becomes STATE_1, and your next function call will check on this state variable, to decide next move (ignore the current call or carry on).
my 2 cents.
If you want synchronous behavior, just add a wait after you make the call.
EDIT: I've added code for the chaining behavior I was talking about. Just replace the result handler each subsequent time you call the remoteObject.
...
remoteObject.function1(...);
...
private var resultHandler1(event:ResultEvent):void
{
...
remoteObject.removeEventListener(resultHandler1);
remoteObject.addEventListener(ResultEvent.RESULT, resultHandler2);
remoteObject.function2(...);
}
private var resultHandler2(event:ResultEvent):void
{
...
}
I achieved the same in two ways: First, as said above the use of state machines. It may get tricky at times. Second, the use of command queues - I think this is the best way to do it... but the downside is that the UI may not be very reflective in this time.
you should perhaps try and make one request with with all the data u want to be recieved synchronous and then make the different classes that need data listen to the correct data for that class.
ex:
// request
remoteobject.GetData();
// on received request
private function receivedData(evt:ResultEvent):void
{
for each (var resultobject:ResultObjectVO in evt.result)
{
var eventModel:Object;
var event:DataEvents = new DataEvents(resultobject.ResultType);
event.data = eventModel;
eventdispatcher.dispatchEvent(event);
}
}
Something like this. Hopes this helps.
No, why would you wish to do that anyway.
Flex makes things asynchronous so that the user isn't forced to sit and wait while data is coming back.
It would be a very poor user expereince if each time an app requested data the user had to wait on it coming back before anything else could happen.
from comment
No you don't need synchronus behaivour. If you're making say 2 calls and call 2 comes in before call 1, but 2 relies on the data inside 1 then you're left with either don't fire off event 2 till 1 comes back (this will slow down your app - much like synchronus events) or implement a way to check that event 1 has come back in event 2's handler (there are many ways you could do this).
If you're firing off many events then why not have a wrapper class of some description that tracks your events and doesn't do anything on the responses until all events are back.
You can use the AsyncToken to keep track of individual requests, so if you are firing of loads at once then you can find out exaclty whats come back and whats not.
You all are somehow mistaken or not using flex from adobe, if you send 2 calls to the server, no matter if each has an individual resquestObject the second one will ONLY be returned after the first one finish, even if the second one takes 1 milisecond to process. Just try the fibonnaci 1/40 example.
Maybe if you call a synchronous XMLHttpRequest calling JavaScript on Flex, you can do this.