I am using ormlite for sqlite database in my android application. It's a login based application and I have database in SD card. For user abc, the requirement is when user login with different user like xyz then application authenticate the user from the server and server replace the db for user xyz. But when I am trying to access the login credentials it is giving the old credentials while the database is reflecting the new credentials.
I also tried:
DaoManager.clearCache();
It is not working also I tried:
DatabaseManager<DatabaseHelper> manager = new DatabaseManager<DatabaseHelper>();
manager.releaseHelper(DatabaseHelperGenerator.getDataBaseHelperInstance())
After this when I tried to fire this query:
Dao<LoginAuthentication, Integer> loginAuthenticationDao = null;
DatabaseHelperGenerator.getDataBaseHelperInstance().
clearLoginDao(LoginAuthentication.class);
loginAuthenticationDao = DatabaseHelperGenerator.getDataBaseHelperInstance().
getUserDao(LoginAuthentication.class);
List<LoginAuthentication> loginAuthenticationList =
loginAuthenticationDao.queryForAll();
It is giving IllegalStateException :Database not open
Looking for help.
Seems to me that you are going in the wrong direction here.
You are assuming that the DAO is caching objects for you but unless you have enabled an object cache on a particular DAO then that's not the case.
DaoManager.clearCache() doesn't clear object caches but instead clears the cached DAO objects.
Once you release the helper, the database connection is closed which is the reason why you are getting the IllegalStateException.
I'd do some debugging of your application or some logging of values to see where the problem lies. Here are some thoughts:
If you are using an object cache, have you tried to disable it? Have you tried flushing the object cache by calling Dao.clearObjectCache()? Again, a cache will only exist if you have turned it on. It is not on by default.
What code are you using to persist the login information? Anything different than other calls?
How about using the Dao.queryRaw() methods to dump the database right after the insert?
Any transactions?
Best of luck.
Related
I am currently running into some issues regarding the realm database and I don't know what the best practices are to tackle this problem.
So I have setup an app which communicates to a server and gets Post Objects through Retrofit stored into my Realm. This post feed is a core part of my app and I want to keep things locally to stay attractive while being offline. The thing is that I cannot store the entire feed list locally as this would be a massive chunk of memory. But I want to make sure that the User gets this content while scrolling through a recycler-view.
The recycler-view currently only shows local Posts and updates them if refresh is forced. I want to implement a load on scroll mecanism that loads Post objects into it while scrolling but this scroll objects should not be stored locally when the app closes.
I thought of creating an additionally in-memory Realm but there is another problem: A Post Object contains a ForeignKey to a UserObject. When I download this dynamic PostObjects and a UserObject changed over this time on the server I want to be able to reflect this changes to every other User on the local persisten Realm too. (To avoid having 2 different UserObjects for the same User)
My best idea i came up so far is to have a
Boolean field on the PostObjects set to true or false to indicate temporary state or not. After the applications closes I would drop all the temporary entries. Is this a viable solution or do I miss anything? I hope you understand my problem and can help.
Edit: My Realm Database contains two relevant objects:
User
Has a name (primarykey), id (global from server), imageUrls etc..
Post
Has a User who created it, again an id and its data (text, date, images...)
Edit2 : What I really need is a type of in-memory Realm that allows me on start up to clone another realm that is used to have data in case of no connectivity. Before the in-memory realm gets deleted I would then override the offline realm with the 5-10 last post entries of the temporary realm. Is such a thing possible?
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 set my application up to store the users data in a SQLite database, and when they get a wifi connection a button appears on a screen refresh that lets them start an IntentService and upload the data to a AppEngine Datastore associated with the application. A result is returned from the datastore indicating success or failure. If successful the IntentService gets a reference to a SQLite database( with application context) and deletes the row. Most of the time this works well however if the user navigates out of the app, and the the app gets destroyed, the row data is not removed from the SQLite database.
I was thinking about switching to a ContentProvider, however I'm not sure if I can delete rows from the ContentProvider if the application is closed, which then wouldn't be any better than the SQLite database.
I could open the SQLite database with Intent Service Context, but then I wouldn't be able to use the singleton pattern, and I would have to deal with the database getting closed unexpectedly.
I could check the back-end to see if the data is present and then delete it on the front end if it is or upload it if it's not, but that doesn't seem like the most efficient way.
I'm wondering if anyone else has solved this type of problem and would like to share their solution with me?
I have started working with databases lately, I was able to create a local database and manage it in my Android app. Now I want to move to higher level with it but I don't know how to do it.
The users in my app need to be able to modify the database, for example insert new data in it. When a user insert new data in the database I want other users to see this change in their copy of the database.
I understand that I will need to store that database on a server or something and synchronize it with the users.
Can anyone tell me the steps to do so?
You should perfom this task in steps.
First, make the local database, and use a system to know when/what changed.
I usually work with triggers myself, but any "mark" is enough to synchronize.
Then, you must make a replica of that database somewhere else. Realise that maintaining the databases is a process, any change in the structure of one database must be performed in all other as well.
Finally, you must implement a method to transfer the data.
So, for an example:
db_local the database in the device.
db_outside the database in the internet.
db_local.trigger -> onInsert
On the applications, check for internet, then connect to your server, then upload the same command to db_outside and run it...
In this step, you must handle connection issues, and if the SQL command was succesfully executed, you have replicated the database content.
Once you have the replicated database, inform a system (like google cloud messaging), that the database was changed, and have the other users pull the info.
I am using parse for chat application in android for storing the data I am using both the server and local database(Parse.enableLocalDatastore()) it is working fine, the problem is with fetching data from the database like if network is not available the data will return from local database and if it is available it will return directly from parse so how can i differentiate between them? should i use query.fromLocalDatastore() method while quering the data or not?
You're going to have to build 2 different queries, one for local data and one for network data, and then figure out which one you want to display on screen.
There are a few scenarios you have to account for :
Server side deletion, addition and update
Client side deletion, addition and update
Not all of these need to be accounted for, only those that make sense for your application.
Keep in mind that when an object is pinned (and not saved to the server), it does not have an objectId, but it does have something called a localId (it's private api but you can see it in the debugger). You can check for the existence of objectId to determine if the object was created locally and has never been saved to the server.