4

I've got a Xamarin Forms app that uses an SQLite database to store user data, including a login token that I use for authenticating with a REST API.

I'm getting a strange issue on Android where updating the app by redeploying it from within Visual Studio causes the data in the SQLite database to revert to an old version (it's always the same old data).

I open the SQLiteConnection inside a DependencyService like this:

public SQLite.Net.SQLiteConnection GetConnection()
    {
        var sqliteFilename = "mydatabase.db3";
        string documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); // Documents folder
        var path = Path.Combine(documentsPath, sqliteFilename);

        var platform = new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid();
        var conn = new SQLite.Net.SQLiteConnection(platform, path);

        // Return the database connection 
        return conn;
    }

The login token is stored in a table in the database that only ever contains one row (the currently logged in user).

Opening the database and reading out this token is literally the first thing I do in App.xaml.cs, after the call to InitializeComponent, and after running an updated Debug or Release build, without fail, the table contains this out of date token. I can then log out and log in again to refresh the token and the app works fine, with the new data persisting correctly over multiple opening and closings of the app.

My question is where is this out of date token coming from?

Some things I have tried to stop it appearing:

  • Did a clean build of the app (including manually deleting the obj and bin folders in the project).
  • Unchecked "Preserve application data cache on device between deploys" in Options -> Xamarin -> Android Settings in Visual Studio
  • Uninstalled the app from the device. Since the data base is stored in the System.Environment.SpecialFolder.Personal folder (which corresponds to /data/user/0/com.example.myapp/files/mydatabase.db3), this should wipe the database as far as I know.
  • Updated to latest version of Xamarin Forms (2.3.4.231) and Xamarin (4.4.0.34). SQLite libs etc are all up to date.

There is only one place in my app where I insert the token into the database (when a user logs in) and I am logging this to the console, and the old token is definitely not being reinserted into the database by my app. There is no db3 file in my project that contains this data. In any case how would it get there?

This issue only began happening in the last couple of weeks, possibly due to an update. Before then, uninstalling the app was sufficient to erase all data.

There's clearly some kind of extra layer of caching of this data that I'm not aware of despite searching the SQLite and Xamarin documentation, can anyone tell me what it is?

5
  • 3
    I cannot speak for Xamarin, but from a pure Android standpoint, you might have android:allowBackup="true" on the <application> in the manifest, in which case the OS may be restoring your data from a backup. Commented Apr 30, 2017 at 21:42
  • @CommonsWare Thanks, that was it! I set android:allowBackup="false" and after uninstalling the app the old data stopped coming back. Unfortunately I then got a crash in SQLite inside System.Attribute.InternalGetCustomAttributes when creating a table, but that's a separate issue I can look into. Hopefully Xamarin Forms apps are not required to have allowBackup set to true. Commented Apr 30, 2017 at 22:14
  • @samgak, I suggest you add this as the answer. Xamarin (Forms) does not require a specific value of allowBackup to be set. Commented Apr 30, 2017 at 23:17
  • @TimKlingeleers done. Do you know why this restore-from-backup would be triggered? It happened even when doing a normal Debug deploy of the app, without uninstalling it first. Commented May 1, 2017 at 0:01
  • 1
    Not a clue at the moment. Perhaps it is supposed to load the backup after removing and reinstalling the app? I'll try to look into it when I find some spare time. Commented May 1, 2017 at 0:06

2 Answers 2

12

As per the comment by @Commonsware, adding android:allowBackup="false" to the AndroidManifest.xml in the <application> tag prevented the old data from being restored.

From the Android docs:

android:allowBackup

Whether to allow the application to participate in the backup and restore infrastructure. If this attribute is set to false, no backup or restore of the application will ever be performed, even by a full-system backup that would otherwise cause all application data to be saved via adb. The default value of this attribute is true.

It's still not clear to me why doing a Debug deploy of an app that was currently installed would trigger a restore-from-backup event.

Sign up to request clarification or add additional context in comments.

1 Comment

I'm seeing it restore a sqlite db on a release install over newly added rows. I don't understand why Google chose to do this.
0

Actually why do you want to store token in SQLite Table. You could use https://www.nuget.org/packages/Xam.Plugins.Settings/ to store token.

1 Comment

Thanks for the link but I'm storing a lot of other stuff as well. It's just that the token is the first thing I read out so I was sure it wasn't being overwritten by my app.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.