I know that, firebase there is a real time database and I have made use of it. But its based on authentication from the user first. What I would like to do is have the firebase realtime database share its content with other apps. Just like a ContentProvider in Android.
When I call :
FirebaseDatabase database = FirebaseDatabase.getInstance();
This is going to get the firebaseDatabase only for my app. I want other apps to be able to use the real time database as well. How can they connect to it?
UPDATE:
Conceptually can a contentProvider solve this issue? since a contentProvider is just an abstraction and it does not care what the datasource is, instead of using sql as the source i could use firebase db. Then since the firebase db is wrapped inside a contentProvider i could then expose a URI for other apps to use and make the contentProvider public. I'll have to look more into this but should be possible since contentProvider is a wrapper for a data sources either network or local. The ContentProvider.query command would return a cursor though, not sure how to make a cursor out of the retrieved firebase data.
Option 1 would be to implement a custom backend serving as an access point to the data via some authentication.
Option 2 would be to make all the data you want to share publicly available and get a reference to that database in the apps in question.
Option 1 would be safer and more reliable and configurable from a single place. Option 2 would be easier to implement.
Related
The android app I am currently developing will mainly run offline. However while online, the users can connect to the DB to download the data they need. Furthermore they are able to manage the data offline, so they can remove the data they don't want to use. The users cannot modify the online database.
I am using Firebase with its Persistence enabled feature, to save the date for online use. My problem is, that I just cannot manage the data properly.
Since firebase downloads the whole database:
Is there a way to choose, which queries I want to download form firebase?
If not, can I delete those queries I don't want to use, from local content?
It looks like you don't want the sync feature of the firebase database.
However while online, the users can connect to the DB to download the
data they need. Furthermore they are able to manage the data offline,
so they can remove the data they don't want to use. The users cannot
modify the online database.
set write as false for this table in the rules and the modification will not be possible, since you have enabled disk persistence firebase will read the newer updates but wont write the user changes. Also it might discard the existing changes of the user(which the user removed) during the sync and put the newer ones from the cloud, so you might(as I have never tried this) end up doing the sync yourself, please search and read up on this.
Since firebase downloads the whole database: Is there a way to choose,
which queries I want to download form firebase? If not, can I delete
those queries I don't want to use, from local content?
You will have to turn off on the sync on the each of your table like shown below
DatabaseReference dbRef=FirebaseDatabase.getInstance().getReference("table-name");
dbRef.keepSynced(false);
Refer here in the docs. I think this has to be done on each node as there is no way to turn it off on the entire firebase realtime DB except disable disk persistance which you want in your case.
IMHO it looks like you are using firebase as a place to store your data in the cloud, in case the sync feature ends up discarding your local changes to sync the online ones you should consider using SQL-lite DB with Room ORM as it will serve your purpose of just fetching the data and modifying it locally, however the tradeoff here is that you will have to maintain the data in a proper manner to query the newer changes or see if there is any updates/deletes on any of the older records.
I am building an Android app, which makes use of Contacts stored in Android Database.
The preferred approach is to use ContentResolver, and then query() as the app's data is exposed by the provider.
Fair enough..!!!
Can, I use Room here for querying the data which are exposed by providers?
Is it a fine approach? As I want to take advantage of abstraction and compile time check and internal mapping?
Not directly.
Room is only for your own internal database.
You could conceivably poll the contacts through its ContentProvider once per day (perhaps through a Job, so this work is done alongside other jobs). This data could then be inserted into your own Room database.
This could have negative reactions from users (why is this App storing my contacts?!). It would also not be updating instantly, only as often as you poll the data manually.
In my app I have SQLite db. I want to introduce sync between devices of my users. Firebase DB looks like an acceptable solution, but Firebase DB is cloud db at first. So, I can't use it as local db if user will reject auth dialog and let him use app, but without cloud-sync.
Now I think about combining my local SQLite db with cloud Firebase db.
For example, when user adds new row to local SQLite db, my app will also put data into Firebase DB. Other devices of this user will catch this event and update their local db. When the user uses authentification and installs app on new device, I want it to download all rows and put them into local SQLite db. That's my idea: use Firebase DB only for synchronizing data, not for storing it at device. Main reason for it is to let user use my app without authentification&synchonization. The second is that Firebase DB is not designed to be used as local db.
I'm right? Is it okay to use Firebase DB with another local DB?
Related question:
link He want the same as I want:
my plan is to offer the user the option to stay offline
If your firebase structure is not too complex you could also make a interface which defines methods like
void addData(Data data);
Data getData(long id);
void editData(Data data, long id);
void deleteData(long id);
then create 2 classes implementing that interface, one using Firebase the other using SQLite.
DatabaseImplementation
FirebaseImplementation
Inside your Firebase implementation, you would publish the data like normal, and publish one new node to something like root/requestUpdate/userId/push/ and push would contain information on where you request an update, and what deviceId published it.
Then have a ValueEventListener tied to that mentioned node, and if it gets a new child, have it look whether the deviceId is the same or not. If it is not, have the FirebaseImplementation getData using the information you got, and then use the DatabaseImplementation, to addData.
That would make sure that whenever a change is made, any other logged in client will know to update its firebase. If the client is not online, the next time he will be online he will do it as ValueEventListener triggers when it is attached. Make sure to loop through all the requested updates to make sure all are made. Also store the push keys of any updates you did complete on a local database that way you dont end up updating more than once.
Basically the firebase will always be up to date and store any changes a user made on a seperate node which is listened to by all clients.
Obviously this solution still has many problems you would need to fix, like figuring out when to delete the requestUpdate node. Logically after every user has synced but how do you determine this? ...
As for the first login, you would need to write a populateDatabaseFromFirebase() method which will do a whole lot of getDatas and addDatas. How you would do that will depend on how your DB looks. You then would store that the user has already logged in with SharedPreferences and the firebase UID.
That all being said, this will only work if your firebase is pretty flat. If you have a complex database, then everything becomes much more complicated and entangled and then it might be worth looking into an external library.
Some options for HTML5 hybrid apps
This is not what the OP asked about, but hopefully useful to some seekers.
You can use any combination of client and server database to implement storing remotely-maintained data in the device so it will be available when offline.
Some client options :
SQLite
(which is using the "native" browser database, works on iOS Safari
and Android webkit browsers)
IndexdDB
(another "native" option, but not supported in early Android, or
fully supported for iOS - so NOT a good option)
JayData
(which provides an abstraction layer from the underlying native implementation)
Lawnchair
(another popular client abstraction - I found the documentation lacking and have not used this for that reason)
Some server options :
MongoDB
RethinkDB
MySQL (for an SQL DB on the server)
and, of course there are many many more.
I am building a mobile app to allow for real time messaging, befriending users, creating groups to both chat and share images with, as well as creating events where users can invite one another.
I have chosen to use Firebase as the online back-end. But, given Firebase uses a NoSQL data model, while Android SQLite uses SQL, when saving data offline in Android what is the conventional way to handle this? Is there a simple way to convert or simply save from NoSQL to SQL, or do I need to build a converter?
(This is especially important for the events, as once created, they must be scheduled in the AlamManager, giving users alerts upon event time)
While you could implement your own solution, truth is, you do not need to build anything from scratch.
There are free Android libraries which could help you. I would recommend you:
SimpleNoSQL
The transition from Firebase to SimpleNoSQL is pretty straight forward, and is mostly the same as if you were using any form of SQL:
1) You get the data from your remote db: you can get this trough a request to your remote server, it doesn't matter what language you are using as long as it can return a response you can catch.
2) You save said data to your local NoSQL db: once you have the information requested, it is up to you what to do with it. You could save it to a TXT file, a SQLite db, NoSQL db, save it to the SharedPreferences, etc.
Hope that helps.
I am creating app that should have offline mode, so previously downloaded data should stored somewhere, the most common way is to store data in SQLite database.
Mostly SQLite database is used with Content Provider in android. I have clear understanding what is the purpose of content provider (to share data between different apps), but in my case application will never need to share the data with other apps in the system.
Content provider has the similar interface as HTTP request (GET,POST,PUT,DELETE).
My idea is to create facade class which can be used like this getAllLatestNews(); firstly it will try to get latest data from the internet, if it fails - data from database will be used and if request is successful it also will save retrieved data to the database. This class will be facade for separating different layers of application (not to make requests from activities directly).
But now I am a little bit puzzled deciding whenever I need Content Provider or not. I can use SQLiteOpenHelper classes to retrieve and save data to the database or even use ORM library to do this.
At first I wanted to implement REST API Pattern B by Virgil Dobjanschi. But now I am not sure about this, maybe it would be better to create facade for Robospice(in my case, network request in the service) requests and do persistence there ?
Please share you thoughts about this topic, I would be grateful for any help.
EDIT
I asked this question because I feel that it is not good practice to make requests directly from activities even if they are made in service under the hood, I want to separate different layers of my application in order to make it more flexible and maintainable.
As you don't intend to share your data, i would say that implementing a ContentProvider is overkill.
Personally im a huge fan of ORM libraries (Currently i use SugarOrm in several projects), so i would go down that road.
Then at app startup, you check whether or not you have an active internet connection, and based on that you either get the latest information online, or retrieve older information from the database.
To seperate the logic a bit, i would most likely implement the getting of online information in a service, which would then store it in the database and broadcast to the activity that the information is now available, and then the activity could retrieve the information from the newly updated database.
Content Providers are absolutely for sharing data between applications and are of no use without this purpose.
If you want to use those data only in your app privately, you could use SQLite databases. Also there other objects available:
Shared Preferences
Files
Content provider has the similar interface as HTTP request (GET,POST,PUT,DELETE)
I don't think so. It's more like to SQL language.