I wonder what is the best way to deal with multiple parallel 'read operations', that is registering a SingleValueEventListener and handling data in onDataChanged event, at Firebase (Java-based/Android). Let´s say, I have three different DatabaseReference locations and three listeners are registered right away,
Is it possible to bundle the whole thing somehow so there would be just one request?
What is the best way to implement a 'wait for', so that code is executed as soon as the last of the three DataChange Events delivers data, without nesting them, so that following would just be registered in the event of the previous one?
There is no way (nor a need) to combine the reads into a single request. The Firebase database client pipelines the requests over a single connection. See my answer here for how this works and why this addresses the concerns about round trip performance that most developers have.
In JavaScript code that is handled by Promise.all(). In Android you can use Tasks to accomplish the same. Doug Stevenson wrote a great series of blog post on this, which I recommend reading for details: part 1, part 2, part 3 (which covers chaining tasks using a Continuation), part 4 (which finally covers running tasks in parallel using Tasks.whenAll(...)).
Related
How to automatically update UI with the new tasks?
For example, while I'm on the tasks page, I load them once. In the meantime, let's say new task are created and stored from my web application to mysql db. I would still see only previously loaded tasks without any idea that the new record is created in the database.
I'm using ListView.builder to display the data, while calling the API on initState(). Also, it might be worth noting, I'm using Laravel with MySql for my backend.
What is the best way to update UI with new data whenever there is a new record in the mysql database?
i have one solution to get real time record/Tasks with out page refresh on UI.
steps
1)Add new column name (is_seen) on Task table default is 0.
2)when tasks list you will show on front end then add is_seen =1 for all that Tasks that you have to show on front end.
3)Run ajax call in interval in Task Tasks Ui page that run after some interval like 3 sec etc and get all unseen tasks (condition is is_seen=0) on Ui Tasks page.
4)when new task create on table that will have is_seen=0.ajax call get that task and show on Tasks list on front end
5)then same time after rendering on new task on task list send ajax call to set is_seen=1 of that task.
I hope you understand this.
This might need a little bit of a more complex setup, as you are trying to build an app that is sort real time.
You could go explore Polling -> where you make call to the api endpoint after an interval of say 30 seconds
Or better yet you could explore websockets.
I would argue websockets is the better alternative.
Polling doesnt require any change on your backend, just a timer countdown of sorts -> Have a look at this : https://api.flutter.dev/flutter/dart-async/Timer/Timer.periodic.html.
For websockets, Pusher ,an abstraction of the low level websocket implementation, is quite common on Laravel and quite straight forward to setup. You could start with with the with this closed source option https://pusher.com. Its easier very well documented and has pretty well maintained Flutter package.
On your flutter app, I would advice a better form of state management like Bloc or RiverPod coupled with the Pusher flutter package (https://github.com/pusher/pusher-channels-flutter), to subscribe and listen to channels and events. The state management bit is just to enable you to work with streams and to have cleaner and maintable code.
Depending on how you architecture of streams you might also need to explore the Streambuilder widget
I wonder what is the best way to deal with multiple parallel 'read operations', that is registering a SingleValueEventListener and handling data in onDataChanged event, at Firebase (Java-based/Android). Let´s say, I have three different DatabaseReference locations and three listeners are registered right away,
Is it possible to bundle the whole thing somehow so there would be just one request?
What is the best way to implement a 'wait for', so that code is executed as soon as the last of the three DataChange Events delivers data, without nesting them, so that following would just be registered in the event of the previous one?
There is no way (nor a need) to combine the reads into a single request. The Firebase database client pipelines the requests over a single connection. See my answer here for how this works and why this addresses the concerns about round trip performance that most developers have.
In JavaScript code that is handled by Promise.all(). In Android you can use Tasks to accomplish the same. Doug Stevenson wrote a great series of blog post on this, which I recommend reading for details: part 1, part 2, part 3 (which covers chaining tasks using a Continuation), part 4 (which finally covers running tasks in parallel using Tasks.whenAll(...)).
This question already has an answer here:
Android Pros & Cons: Event Bus and RxJava
(1 answer)
Closed 3 years ago.
I am confused about the difference between EventBus and RxJava in android. I need to implement one of them for my issue about notifying some components when some changes have been done, so that they can update their state.
Also, I read that EventsBus has became deprecated over RxJava and I don't know if this information is true or not.
EventBus and RxJava are different in their nature.
EventBus is just a bus as the name suggest - it provides the mechanism to subscribe and publish events to the "bus", without you caring how the wiring is done, what this "bus" actually is, etc. In the context of Android, the EventBus is just an easier way to deal with sending and receiving Broadcast messages with less boilerplate.
RxJava on the other hand is much much more powerful than that. Yes, you can subscribe and publish events, but you have far more control over the process - frequency, on which thread everything happens, etc. The main power of RxJava (in my opinion) is that you can manipulate the data being published very easy, using some of its tons of operators.
To sum up - if you only care about publishing some events and performing some actions when received - you'd probably be better off using the simplest of the two, namely some kind of Bus, or even plain old BroadcastReceivers. If you will also benefit of transforming the data, handling threading or simplified error handling - go for the RxJava approach. Just keep in mind that RxJava generally has a steep learning curve, so it takes some time to get used to its concept.
To understand RxJava, think of a list. Today manipulating a list like transforming, splitting, merging can be done easily using functional methods (map, groupBy, etc). RxJava uses the same principles except that its main target is not list but stream. Stream is asynchronous, often live data such as websocket channel or online movie.
Event bus comes from the needs to decouple classes which in Android are often bound with life cycle. Tight coupling of network callback and Activity's Views as an instance, has been a cause of numerous null pointer exceptions. Event bus with its publisher-subscriber pattern alleviates this issue.
How does it get mixed with RxJava ?
To begin RxJava incorporates Observable pattern. Here an Observer watches an Observable and reacts when an event arrives. Observable has several sub-classes, among which is Subject that has the properties of both Observable and Observer. Since it works by trapping an event and publishing it to subscribers, it technically functions as event bus.
Is it wise to use RxJava as event bus ? No. RxJava would introduce unnecessary complexities for simpler purposes. Only use it if the app does manipulate streams. For example pairing frames from a movie stream and subtitles from another stream. If the app simply consumes a REST API and needs to decouple the callback from activities/fragments then event bus is enough.
Live #Vesko wrote, RxJava and event bus differ in their nature and may serve to solve different problems. Nevertheless, there are some scenarios in which both of them can solve the same problem (although at different costs), and this might be the reason for why many people confuse these two concepts.
RxJava is conceptualy similar to Android LiveData that was released not so long ago, and to better understand these concepts, as well as event bus, I suggest you read my post. In the post I go over these very concepts, describing the scenarios in which we should use one over another and the pros and cons of using one rather than the other. I think it may be useful to you:
When and why to use LiveData
If you want to fetch data from sever and update UI, use RxJava + Refrofit. If update UI or do some operation without fetching data, EventBus is enough.
I'm constructing an API which is going to be used by an Android and an iPhone app. The app gets a list of events which can regularly be updated. There are currently two ideas.
Creating it using pagination so that it first loads the first 10 events to load results on the screen, and when the user scrolls further it should load more events. I then regularly poll the API to see if there are any new events.
First get the paginated list of id's of events (also first 10), after which the apps should get the full event details in separate threads using one call for every event. In that way it can load all events simultaneously which supposedly makes it faster.
I tend to lean more towards the first solution because it's more simple, but somebody else said the second is a way better idea. I have the idea that the separate threads only add complexity to the case and don't increase the speed significantly. I know that the best way to know is to test it, but building both and testing it takes a lot of time. I therefore wonder whether there are any best practices in getting a continuously updated list of events from an API.
So; which of the two do you think would be best and why?
It depends on the amount of data your events contain. If each event description is only a few fields don't bother to load each event in a separate thread, the overhead will kill any possible performance gain - just get all data in the get events request.
If it is a lot of data per event description, you can argue whether you really want to preload all event descriptions before the user selects an event - probably the user will never click on any of the events, then you did load the data for nothing.
That said, it is also not a bad idea to prepare your API to enable both: Get a list of short event descriptions and a call to get event details for a certain event (or a list of event ids), or get a list which contains the full event descriptions.
I'm using Fragments and LoaderManager. I have to launch an unknown number of tasks, and they might be run in parallel (otherwise I'd just reuse one and only one loader). For example, I have a listview, and each row might have a button to save the content of that row to a webserver. The user could initiate a save request on multiple items in parallel.
private int nextId = 0;
private void onClickListener() {
Bundle bundle = new Bundle();
bundle.putNextData(...);
getLoaderManager().initLoader(nextId++, bundle, this);
}
I could try bookkeeping myself, so create a pool of loaders manually and reuse them when possible, seems like it might be something already implemented by the API?
Thanks
I don't think you should use a Loader for saving data to a remote server.
Instead, use an IntentService or something similar to process a queue of "save" operations. This way, your communication with the web server can be batched, collapsed (i.e. multiple queued saves for a single item can be collapsed into one operation), and will live beyond the lifespan of your activity if need be.
A save queue processed by an IntentService (or equivalent) is also a great way to retry failed operations with backoff, since you can implement delayed retries with exponential backoff using AlarmManager.
An IntentService or bound service are always good approaches for that.
As Roman points, note that enqueuing several requests and called them separately is not highly recommended (it is very likely that you give a lot of work to the radio connection - when using data - which among other things drain your battery. Here is must-read about that)
I'd personally recommend to use a bound service with a queue of requests and a pool of threads available (that approach gives you full control for more complex network operations like in your case). There are more details on the approach here and a testcase working example over here.
Update us about your progress.
You are at the right direction, let me just help you a bit.
Reusing is indeed a good idea, and you do not have to worry about it because Android did it for you(Or Java actually ;)
It called ThreadPoolExecuter, you can start as many tasks as you wish and he will only open the predefined number of threads.(Best practice is trying to open as many threads as parallel network connection can be run on the device. From my research it is between 4 - 9).
And if you are trying to download same URL twice may be you can protect your self and open only one task for it.