Start a new topic
Answered

Xamarin Datastore instance best practices

Hi,

I have two datastores for my Xamarin Forms app, I have tried making these public static instances so they can be referenced from other classes that need them but it works very sporadically. That is, it will sometimes throw exceptions when trying to access these instances. Is there a performance penalty for using class level objects for the datastores?



Best Answer

Hi Vinay/Pranav,


Looks like the latest release 3.0.11 resolves these issues.


Thanks for your assistance!


Just to add to this, I have found some strange behaviour where if I logout and login I get an ERROR_DATASTORE_CACHE_FIND_QUERY  with the exception message "An exception was thrown while trying to find entities in the cache.Error in the query expression used to find entities in the cache." Does it simply mean that it can't find the entities or that the cache does not exist? I am also getting SQLite.Net.SQLiteException: Busy exceptions where these local instances are being created.

Michael,


A fix for this problem has been made and tested and is available for download at the following URL.


http://devcenter.kinvey.com/xamarin/downloads


The release is Xamarin SDK v3.0.9.


Please download and test the solution at your convenience and let us know if it resolves test problem to your satisfaction.


Thanks,

Pranav

Kinvey


 

Hi Michael,


Quick question: when you upgraded to using 3.0.9 to resolve the SQLite issue, did you also add a reference to `Mono.Data.Sqlite`, as per the Getting Started guide?  It is only after adding this reference that the SQLite fix will work.


Thanks,

Vinay

Kinvey


Hi Pranav,

Unfortunately I am still seeing this issue after updating to 3.0.9. Is there any other information you think I am missing?

Michael,

 

ERROR_DATASTORE_CACHE_FIND_QUERY means you getting an error while finding entities by query in the local cache.


  1. Can you please provide relevant code which is causing the error?
  2. Can you also share steps to reproduce the issue?
  3. Have you checked http://devcenter.kinvey.com/xamarin/guides/caching-offline#?
  4. Have you ever called "clear" on the datastore? It destroys the local cache for the store. You will need to pull fresh data from the backend to start using the cache again.



Thanks,

Pranav

Kinvey

Pranav, the following sequence will always throw the exception on iOS and Android:

  • Login User
  • Sync Collections
  • Query Collection (no Issue)
  • Logout User
  • Login User
  • Sync Data
  • Query Collection (Exception thrown here)

Michael,

  1. How are you confirming that the 2nd Sync data call is getting completed?
  2. You are getting "An exception was thrown while trying to find entities in the cache". That means the entities which you are trying to find after 2nd sync call are not present in cache. If your Sync Store has pending local changes, they must be pushed to the backend before pulling data to the store. Check http://devcenter.kinvey.com/xamarin/guides/datastore#Pull
  3. What results are you getting when you use other datastore types i.e. Cache and Network?
  4. Can you please confirm "SampleItem" is correctly configured as you are getting "no such table: SampleItem"? Does it have any data?


Thanks,

Pranav

  1. The SyncAsync call is awaited so it should be completed before the following query.
  2. There aren't any pending changes as I am only logging in and out without adding data to the collection.
  3. I get the same error for the Cache datastore. 
  4. SampleItem is configured correctly. If I restart the app after the failed Query and perform the same query a result is returned. Here is a video showing the issue. https://www.youtube.com/watch?v=xBIbX6I08dc&feature=youtu.be

It seems like even though I await the SyncAsync() call the SQLConnection has not properly completed. Could this be related to the SQLIte issue found here?

Michael,

I don't find anything wrong with your usecase. I reviewed the SQLite issue that you have mentioned in your earlier comment. Looks like it's a bug in our Kinvey Xamarin-Starter. Can you please try the workaround that is mentioned in Here ?

If it doesn't help, then I will need to take engineering's inputs on this issue.

Thanks,
Pranav
Kinvey

 

Pranav,


I was the one who submitted that issue, so even with that workaround for the driver issue I am still seeing the issue.

Michael,

Okay :)

I just found that engineering has set this issue for 'code review'. I will let you know once it is deployed.
Will keep you posted on the progress.

Thanks for your patience!

Thanks,
Pranav
Kinvey
MLIBZ-1815

 

Answer

Hi Vinay/Pranav,


Looks like the latest release 3.0.11 resolves these issues.


Thanks for your assistance!

Hi Pranav, 

To be sepcific I can repeat this by doing the following, logout, login, do datastore sync() then perform a query. See below for code:

 

LoginPage.xaml.cs

 messageLabel.Text = "";
			var user = new User () {
				Username = usernameEntry.Text,
				Password = passwordEntry.Text
			};
            try
            {
                Kinvey.User kinveyUser = await Kinvey.User.LoginAsync(user.Username, user.Password);
                IsRunning = false;
				await Navigation.PushAsync(new HomePage());
            } catch (KinveyException ke)
            {
				messageLabel.Text = "Login failed: " + ke.Description;

            }

   

HomePage.xaml.cs
public partial class HomePage : ContentPage
    {
        DataStore<SampleItem> sampleDataStore = DataStore<SampleItem>.Collection("SampleItem", DataStoreType.SYNC);
        DataStore<AssetItem> assetDataStore = DataStore<AssetItem>.Collection("AssetItem", DataStoreType.SYNC);
        public HomePage()
        {
            InitializeComponent();
           syncDataAsync();
...

async void syncDataAsync()
        {
            await sampleDataStore.SyncAsync();
            await assetDataStore.SyncAsync();
            await DisplayAlert("Finsihed Sync", "Done Syncing", "OK");
            activityIndicator.IsVisible = false;
            activityIndicator.IsRunning = false;
        }
...
//Do Query
List<SampleItem> sampleByQuery = new List<SampleItem>();
            var query = sampleDataStore.Where(x => x.BottleBarcode.Equals(e.scannedItem));
            sampleByQuery = await sampleDataStore.FindAsync(query);

 

The following exception is thrown AFTER data has been synced when I try to perform the query "[ERROR] FATAL UNHANDLED EXCEPTION: Kinvey.KinveyException: An exception was thrown while trying to find entities in the cache.Error in the query expression used to find entities in the cache. ---> SQLite.Net.SQLiteException: no such table: SampleItem"

This seems odd as the datastore should be initialised as I await the syncasync() call. However if i restart the app without logging out then in again this problem does not occur.

Login or Signup to post a comment