j7nn7k
j7nn7k

Reputation: 18612

Azure mobile service: Define a Table only locally

I'm using offline sync in a Xamarin app. I have the following scenario:

I have a couple of tables which sync fine and one table called LocalOnlyTable which I don't want to sync. I just want to read/write it locally.

The problem appears when I pull one of my tables like so:

await exerciseTable.PullAsync(string.Format("{0}ItemByFK", typeof(Exercise).Name), exerciseTable.CreateQuery());

I get a MobileServicePushFailedException saying 404 LocalOnlyTable does not exist.

I'm wondering why Mobile Services tries to push/pull the LocalOnlyTable and How can I prevent Mobile Services from trying to sync LocalOnlyTable?

Upvotes: 1

Views: 1027

Answers (2)

Alfred
Alfred

Reputation: 41

Just came across your issue here and thought of sharing my solution.

1) Create a custom TableSyncHandler to block off local-only tables:

public class TableSyncHandler : IMobileServiceSyncHandler
{
    private readonly IMobileServiceClient _client;
    private readonly HashSet<string> _excludedTables = new HashSet<string>();

    public TableSyncHandler(IMobileServiceClient client)
    {
        _client = client;
    }

    public void Exclude<T>()
    {
        _excludedTables.Add(_client.SerializerSettings.ContractResolver.ResolveTableName(typeof(T)));
    }

    public Task OnPushCompleteAsync(MobileServicePushCompletionResult result)
    {
        return Task.FromResult(0);
    }

    public Task<JObject> ExecuteTableOperationAsync(IMobileServiceTableOperation operation)
    {
        if (_excludedTables.Contains(operation.Table.TableName))
        {
            return Task.FromResult((JObject) null);
        }
        return operation.ExecuteAsync();
    }
}

2) When you are initializing MobileServiceClient's SyncContext, register the tables you want to exclude to this syncHandler, and then initialize SyncContext using the syncHandler:

_store = new MobileServiceSQLiteStore("YourStore");
_store.DefineTable<User>();
_store.DefineTable<LocalOnlyTable>();

_syncHandler = new TableSyncHandler(client);

// LocalOnlyTable is excluded from sync operations
_syncHandler.Exclude<LocalOnlyTable>();
await client.SyncContext.InitializeAsync(_store, _syncHandler);

Disclaimer:

  1. This has not gone to production yet, so I don't know if there will be performance impact, but seems to be working fine so far in testing.
  2. This solution is based on Azure Mobile Services client v1.3.2 source code. It's not doing anything (pull/push) when the synchandler returns null result. This behaviour can possibly change in the future.

Upvotes: 4

phillipv
phillipv

Reputation: 1717

All actions take using the MSSyncTable APIs are tracked to be sent to the server. If you have a table you do not want to track you shouldn't use the MSSyncTable APIs to insert/update records.

You should be able to use either the SQLiteStore methods (like upsert) or execute SQL on your SQLite Db directly for your untracked tables.

Upvotes: 2

Related Questions