Necessity of storing variables in Firebase Database - java

So I am wondering about how necessary it is to store variables in the realtime firebase database if I want all Users at access the same dynamic variable.
So for instance, I have a arraylist that stores the list of open games, and if I want this list to update in realtime for every user should this List in firebase realtime database?
Sorry for the simplicity of the question

Yes, it may be a simple question, but it surely pops in head of everyone, once.
I think for updating any list dynamically in real time, would require you to access any kind of database.
It is not necessary to have it on Firebase database, but any database online, that can tell every open instance of your app that the list has to be updated at a particular instant.
The main reason of why you need it to be on database is updating it in real time and that too dynamically.
If it's not dynamic, meaning the content that you need, can be hardcoded then one way would be placing everything you need in your code and using timer or something like that to fire at particular moments to update things in your app.
Also that aside, sorting, storing and changing data is much simpler using a database, which also becomes one more reason for you to use a database like Firebase to keep content of your app that has to be updated frequently in real time.
You can know more about database in this Google link, I found.

Related

Android Firebase how to handle real time server to local database connection

As for similar questions on this topic and on ChildEventListener, there is no relevant answer, so heres mine.
I have a local SQLite DB which holds all the data, I also have Firebase realtime database which I'm updating with new entries or real time changes across all users. I'm currently doing it with the use of ChildEventListener as follows:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getDatabase().getReference();
DatabaseReference childRef = rootRef.child("my_root");
ChildEventListener eventListener = new ChildEventListener()
{
....
};
childRef.addChildEventListener(eventListener);
As for functionality, With this code I can get realtime changes on childs, get new entries, deleted childs and everything I need but there is one problem. When this specific activity with the listener loads up, the onChildAdded listener gets called enormous amounts of times for every child on this root, as stated on the documentation:
child_added is triggered once for each existing child and then again every time a new child is added to the specified path
So I though to gain focus on the items that I really need and I have done it with:
rootRef.orderByKey().startAt("-WhatTF123456789")...
But then I have lost my CRUD capabilities because it's listening to the new entries and not all of them.
So I came up with a solution. Keep node with all the changes that has been made to the FireBase database and a node with all the users that have read and made the changes to the local DB to know who needs an update, Then use addChildEventListener to this specific node. But that seems redundant.
What is my options to handle this kind of situation?
The onChildAdded listener gets called enormous amounts of times for every child on this root.
As you already mentioned and as the docs states, this is the expected behaviour. Usually, is not recommended to attach a ChildEventListener on a node (root node) that contains huge amount of data. Please be careful about this practice because when downloading large amount of data, you can get erros like: OutOfMemoryError. This is happening because you implicitly download the entire node that you are listening to, along with all the data beneath it. That data might be present as simple properties or, as complex objects. So it can be considered a waste of resource and bandwidth. In this case, the best approach is to flatten the database as much as possible. If you are new to NoSQL databases, this practice is called denormalization and is a common practice when it comes to Firebase. For a better understanding, I recommend you take a look at:
This video, Denormalization is normal with the Firebase Database.
Official docs regarding Best practices for data structure in Firebase realtime database.
My answer from this post: What is denormalization in Firebase Cloud Firestore?
This article, Structuring your Firebase Data correctly for a Complex App.
This article, NoSQL data modeling techniques.
Please also note that when you are duplicating data, there is one thing that need to keep in mind. In the same way you are adding data, you need to maintain it. With other words, if you want to update/detele an item, you need to do it in every place that it exists.
I also recommend you to see the last part of my answer from the following post:
What is the correct way to structure this kind of data in firestore?
It is for Cloud Firestore but same rules apply to Firebase realtime database.
But then I have lost my CRUD capabilities because it's listening to the new entries and not all of them.
Everything in Firebase is about listeners. You cannot get realtime updates for objects within a node, unless you are listening to them. So you cannot limit the results and expect to get updates from objects that you are not listening to. If you need to get updates for all objects within a node, you need to listen to all of them. Because this approach isn't practical at all, you can either use denormalization as explained above or to restrict the results by using queries that can help you limit the amount of data that you get from the database. Regarding your solutions, the second one is much preferred but you can also consider another approach which would be to load data in smaller chunks according to a timestamp property, or according to any other property that you need.
Edit: According to your comment:
Can you please provide tests for each solution (1.denormalization, 2.my solution) examine use of bandwidth and resources and which one is really preferred?
All data is modeled to allow the use-cases that an app requires. Unfortunately, I cannot do tests because it really depends on the use-case of the app and the amount of data that it contains. This means that what works for one app, may be insufficient for another app. So the tests might not be correct for everyone. The denormalization process or your solution is entirely dependent on how you intend to query the database. In the list above, I have added a new resource which is an answer of mine regarding the denormalization tehnique in NoSQL databases. Hope it will also help feature visitors.
I would make a root node with the name, for example, MaintenanceUpdate.
All clients are subscribed to changes here.
As soon as MaintenanceUpdate becomes = true, all clients unsubscribe from changes to the main "database". And then (when MaintenanceUpdate = false) are re-subscribed again.
At this time you are updating the database.
I have similar requirements, with Firebase and Room, while I've solved it alike this:
public class BaseModel extends BaseObservable implements IDataModel {
/** Sqlite default PK */
private int itemId = 0;
/** Firebase uniqueId */
#ColumnInfo(name = SqliteBaseHelper.KEY_FIREBASE_UNIQUE_ID)
protected String uniqueId = null;
/** Firebase lastSync */
#ColumnInfo(name = SqliteBaseHelper.KEY_FIREBASE_LAST_SYNC)
protected long lastSync = 0;
...
}
this means, when a local record has a KEY_FIREBASE_UNIQUE_ID which is null and the KEY_FIREBASE_LAST_SYNC is 0, it has to be inserted into Firebase - else it would check, when running a synchronization AsyncTask, if the local or remote record needs to be updated. this is because the main issue is, that when inserting remotely, the ChildEventListener will attempt to synchronize duplicates to the same client - unless having such indicators for the synchronization status in place, locally and remotely. the local primary keys might vary across the clients (depending for how long they were offline and how many records where locally inserted during the offline state), while the synthetic KEY_FIREBASE_UNIQUE_ID is used for identifying them; it's the "key to success".

Backend structure suggestion for real time update application (Firebase)

I was trying to develop an mobile app which have some similar idea just like Uber, which is real time update driver & customer location. So here I am seeking for suggestion for what I was thinking for the app structure.
For what I research, in order to provide fast real time update location, I may need to make use of real time database such as Firebase for the backend. So, I was thinking to combine 2 different type of database to achieve what I was thinking...
Firebase - For real time fast update user location
MySQL - For backend api business logic
However, I have no experience with firebase, so I hope you all can give some advise. I plan to only store the user location coordinate information in firebase database, then retrieve it from mobile app to update realtime.
My problem is I not sure should I forever persist those driver coordinate data in firebase database? Since the coordinate data keep changing update in firebase, so should I delete those coordinate data from firebase as soon as the driver have reach the destination. (No need to keep those data persist, only real time data keep change on firebase)
Thanks for reading such long question, I will also happy that if you all can remind to me any other concern if I use 2 different database for my application.
You'll typically keep a list of drivers and their locations in Firebase:
driverlocations
driver1id: location
driver2id: location
This means that you're not adding new data, but updating existing data. So you don't have to worry about the list constantly growing.
To ensure you don't have stale data for drivers that closed the app/stopped driving, you can use Firebase's onDisconnect() handlers to remove the data when they disconnect.
Now querying this data for nearby drivers is still tricky. You'll want to look at GeoFire for that. I recently explained why that is needed and how it works here: Sort array by distance near user location from firebase

How to retrieve data from a database efficiently?

I'm building an android app, and I need to retrieve a list of users from a database. I know how to write the query. I will have back a list of object.
I was wondering how to do this in an efficient way considering that I need that list in 3 activities. I think that repeating the same code for 3 times, in 3 different activities is not optimal.
Thanks
As per you comment you are fetching this user data from server,
you can consider following:
make a web service to retrieve user list.
call the web service first time you need list of users.
cache this list in shared preferences or SQLite DB, depending upon size of list.
use it where ever you need.
refresh your list from server periodically or as per your need.

What is faster - a Cursor or ArrayList?

I have an SQLite database which I have to be constantly retrieving data from. Changes may be done to the data between each retrieval.
My goal is to maximize the app performance, so what is the fastest way to do this retrieving?
I can imagine 2:
constantly opening and closing new cursors
query all data at the beginning and store it in an ArrayList. When changing the data, change both SQLite DB and the ArrayList using indexOf.
---- EDITED ----
I need the data to create markers in a google's map.
I have considered using CursorLoader but as I don't need to interact whith other apps I don't want to use Content Providers.
Would creating a custom loader be a good idea?
In short, while it's not always that simple, the fastest way to do things is all at once.
Constantly making calls to and from a database can really make your apps performance bottleneck, especially if it's to a server and not just your devices SQLite database.
Depending on what you're doing with the data, you may be able to look into something like a CursorAdapter which handles the display of rows from the database, and each time you insert/update a row, the CursorAdapter will update the ListView accordingly. It also handles the opening/closing/moving to next of the Cursor, making it very readable and easy for developers to follow.
Again, however, try to do things in as few calls as possible. If you stick to using an ArrayList:
Make one call in the beginning for all items.
Loop through that cursor and add items to an array list.
Use the array list as a cache. Sure, you could update the DB each time you update the list (which might be safest, IMO), or you can just loop through the list and insert/update/delete when the app closes. If you take that approach, make sure you do so in a method like onPause(), as it is one of the earliest methods in which an Activity can be killed.
Perfect use case for a CursorLoader. Given a query, it'll keep your list adapter up to date with the latest data, assuming you notify when changes happen in the DB. It also conveniently handles activity lifecycle events for your (ie. it'll close the cursor when the activity finishes, stop updating when it pauses, etc.).
The fastest way is obviously to not use a database at all. However, that is clearly not a solution unless you find some way of exposing your array to access from elsewhere.
Using a database is a convenient way of centralising the data so many users can access the data and have the data up-to-date at all times. Unfortunately this is the slowest option.
Choosing your middle-ground between speed and availability is a difficult task. You have to find a balance between stale data and throughput.
If, for example, you would be comfortable with a picture of the data that was valid just 5 seconds ago then you could probably cache the data locally in your array and arrange for some mechanism to keep it up-to-date running behind the scenes.
If a 5 minute lag was acceptable you could probably arrange for a regular push to database.
Also, any mechanism you use must also handle parallel changes to the data - perhaps two users change the same datum at the same time.
You just need to decide on where to strike your balance.

Optimised update ListView in android

Till now, I have coded apps which load listviews completely from web(parsing,etc) or completely from local database. What I intend to develop is a listview which will load from existing local database, and check the web database and fetch only those entries which do not exist in the local cache, and then update the local cache with those new entries.
I had a naive idea of implementing it. There would be a single value in local data about the number of entries in local database. Similarly, there would be a value of number of entries on the web database. Then we can exactly fetch the required number of entries from the web, instead of fetching the entire list again.
Is there some better/easier way to do it?
I found a solution to this. The better thing to do would be to do this checking on a middle layer server. It would be like a 3 layer application. There would be a middle layer which would store all the posts seen by the current user. So next time user wants to update himself, the middle layer can check what results were posted back to him last time

Categories