0
votes

I'm trying to reproduce the post "Getting Started with Azure Mobile Apps’ Easy Tables" from James Montemagno. However I'd like to make some changes and/or additions, so that the result fits into my personal interests. Everything works fine except one issue:

PullAsync (from IMobileServiceSyncTable) throws an CancelledBySyncStoreError exception !!!

(I'm executing the Xamarin Forms App as an Android App - target decice is a Nexus 7 with Android Version 5.1.1)

Details are as follows:

In the Azure Portal I've setup an Easy Table. The schema is as follows:

Azure Schema Definition of Easy Table

The table in the Portal seems to be correctly established, because I can integrate the remote table in Visual Studio (2013) Server Explorer. Schema details as seen from the Visual Studio are as follows:

Table Schema as seen by Visual Studio

Or:

CREATE TABLE [dbo].[FirstHighScores] (
    [id]        NVARCHAR (255)     CONSTRAINT [DF_FirstHighScores_id] DEFAULT (CONVERT([nvarchar](255),newid(),(0))) NOT NULL,
    [createdAt] DATETIMEOFFSET (3) CONSTRAINT [DF_FirstHighScores_createdAt] DEFAULT (CONVERT([datetimeoffset](3),sysutcdatetime(),(0))) NOT NULL,
    [updatedAt] DATETIMEOFFSET (3) NULL,
    [version]   ROWVERSION         NOT NULL,
    [deleted]   BIT                DEFAULT ((0)) NULL,
    [Name]      NVARCHAR (MAX)     NULL,
    [Score]     FLOAT (53)         NULL,
    [PlayedAt]  DATETIMEOFFSET (3) NULL,
    PRIMARY KEY NONCLUSTERED ([id] ASC)
);

As you can see, I've added three columns in the portal manually: Name, Score and PlayedAt. The corresponding SQL data types are String, Number and Date. All of the remaining schema entries have been generated automatically by the Azure Portal scheme designer.

Next some infos about my Xamarin Forms App:

The model class of my Azure Easy Table is as follows (Azure Table name and C# class name are the same (!)):

namespace AzureHighScoresFirstApp
{
    public class FirstHighScores
    {
        [Newtonsoft.Json.JsonProperty("Id")]
        public string Id { get; set; }

        [Microsoft.WindowsAzure.MobileServices.Version]
        public string AzureVersion { get; set; }

        public String Name { get; set; }

        public DateTime PlayedAt { get; set; }

        public float Score { get; set; }
    }
}

The following Initialize-Method runs without (!) exception:

public async Task Initialize()
{
    try
    {
        this.mobileService = new MobileServiceClient("http://peterstestapp.azurewebsites.net");

        // setup local sqlite store and intialize our table
        const string path = "syncstore.db";
        MobileServiceSQLiteStore store = new MobileServiceSQLiteStore(path);
        store.DefineTable<FirstHighScores>();

        await this.mobileService.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler());

        // get our sync table that will call out to azure
        this.scoresTable = this.mobileService.GetSyncTable<FirstHighScores>();

        Debug.WriteLine("Did Initialize");
    }
    catch(Exception ex)
    {
        Debug.WriteLine("{0}", ex.Message);
    }
}

The SyncScores-Method looks as follows:

public async Task SyncScores()
{
    try
    {
        IMobileServiceTableQuery<FirstHighScores> query = this.scoresTable.CreateQuery();

        await this.scoresTable.PullAsync("allScores", query);  <== **crashes**

        await this.mobileService.SyncContext.PushAsync();      <== not reached
    }
    catch (MobileServicePushFailedException ex)
    {
        string ErrorString = string.Format("Push failed because of sync errors: {0} errors, message: {1}",
            ex.PushResult.Errors.Count, ex.Message);

        Debug.WriteLine(ErrorString + " - " + ex.PushResult.Status);
    }
    catch (Exception ex)
    {
        Debug.WriteLine("Exception SyncScores: " + ex);
    }
}

The SyncScores- and the Initialize-method share the following instance variables:

private MobileServiceClient mobileService;
private IMobileServiceSyncTable<FirstHighScores> scoresTable;

If I call SyncScores (within a Read- or Write-Method from my Xamarin Forms Client), an MobileServicePushFailedException-Exception with the error message 'CancelledBySyncStoreError' is thrown.

In my opinion the Exception is thrown, because the SQLite-Client in the Xamarin Forms App, being instructed about the table scheme through the definition of my C#-class 'FirstHighScores' and the remote table scheme of the corresponding Azure Easy Table don't exactly match.

But I can't figure out the difference ....

Sorry, some ideas?

1

1 Answers

0
votes

I've found a workaround by myself.

Maybe during development of my app, some details according to the data base scheme could have been altered (although I really can't remember this).

When the design of the database model was stable, I just created a new MobileServiceSQLiteStore object (means: I've choosen another name for the database storage) ... and the synchronization methods worked fine!