Sync Mobile Apps with Azure using Change Tracking API
Published Mar 06 2020 09:28 AM 11.3K Views
Microsoft

If you are creating a mobile app that will work sending data back and forth from the cloud (I guess that 99% of the apps fall into this use case), you will have at some point the need to sync data between the app and the cloud itself.

 

If you are a code-first person, grab it right away here: Using Azure SQL Change Tracking API to Sync mobile Apps data with the Cloud

 

This may be needed for several reasons, here's a few:

 

  • The app also offer a desktop or website experience and data can be managed from there too
  • The app was not connected to the cloud for a while and some data processed in the cloud needs to be sent to the app
  • A user freshly installed the app on a new device and of course now he/she want to see not only the new data but also the preexisting one

 

Let's see the process a bit more in detail and let's also generalize a bit so we can came up with a solution that will work on all possible situations.

 

 

App to Cloud Sync

Synchronizing changes done on the app while it was offline is the easiest part. Figuring out what data has been created, changed or deleted in the application while it was offline is quite easy. Those changes are done directly from the application, so it has knowledge of them. You just need to make sure you keep track of those changes, for example put them in a queue, so that they can be sent to the cloud as soon the connectivity is back.

 

On a mobile device, you never know if connectivity will be available

 

There is nothing new here, as the concept of Connection Resiliency should be quite familiar to all mobile developers. On a mobile device, you never know if connectivity will be available or the endpoint you need to call will there to answer your requests. So you need to code defensively, making sure retry logic and requests queuing is something your application implements correctly. As I'm more experienced with C#, I'm aware of frameworks like Polly and resources like the following:

 

 

I'm pretty sure there are many resources around this topic, for all the major mobile platform and languages. I'm definitely not a Mobile developer, so if you have any comments or resource to share, please do :).

 

Cloud to App Sync

Sending data from the cloud to the app is way more tricky. You want to do it in the most efficient way, to spare bandwidth and device battery life, so you need a way to know what has changed since the last time that specific user and device synced. As data is surely stored in a database of some sort, you also need some efficient method on the database side to make sure you can quickly get everything that is new or changed and that is in the scope for that specific user/device. If your mobile application is successful, this means that you may literally have millions and millions of rows or documents to scan and check for changes.

 

Not an easy task: all hope is lost then? Just send back the whole data set and that's it? Of course not! We don't want to just be developers, but better developers, right?

Modern databases can help a lot in tackling this challenge. Azure SQL, for example, has a feature called Change Tracking that, guess what?, will take care of keeping track of changes for you.

Here's a very high level of how it works:

 

Sync Mobile Apps and Azure using Change Tracking API-1.PNG

 

But let's dive into it a bit deeper, to see how it can help us creating a nice API that, when called, will return all the data that has been inserted, updated or deleted since the last time it such API was called from a user/device.

 

The sample scenario

Imagine that you are creating an application to track your Running Sessions. Many people loves running, hiking or cycling, so you are surely aware of application like Runtastic, Strava and the likes.

 

First Sync

The first time your application starts after being installed, it will need to query the server, (once the user has logged in), and download all the existing data for that user.

 

curl -s -k --url https://localhost:5001/trainingsession/sync

 

Here's the JSON you may expect to receive from the sync REST endpoint:

 

Sync Mobile Apps and Azure using Change Tracking API-3.png

 

The JSON document has two sections. The Metadata section will tell you if you are receiving the Full set of data or just the change set, and an identifier of the version of data you are receiving. In the above sample, we are receiving a Full set, that comes with the version number 123. This number has no special meaning: it just represent a number associated with the current version of data. Is a way, for us, that we'll use in future to tell the server that we won't need all that data again, since version 123 it's our starting point. In a hypothetical timeline, this is our "T0", the start of our timeline. We'll just need to get the changes from there and on.


The Data section contains all the data we need to use to populate our application so that it will show all past Running sessions. Nothing complex here. You may literally save that part of the JSON as is, and use it in your app. I think it will still be better to save it into something like SQLite, but that's up to you.

 

Subsequent Syncs

The users loves our application and they keep using it. We also created a nice website where they can play with their data, slicing and dicing to analyze their performances, adding title and notes to their sessions, and using some clever AI service to analyze their performance and get a customized plan to improve in specific areas. Of course, some of the processing needs to be done on the cloud and the sent back to the app. So the app needs to sync again, this time not to send new sessions, but to get updates from the cloud.

 

This is what it can expect to receive, exactly from the same _sync_ endpoint it called before. This times the app call the REST endpoint sending also the version number it has received before: 123.

 

curl -s -k -H "fromVersion: 123" --url https://localhost:5001/trainingsession/sync

 

The answer, this time, will be something like this:

 

Sync Mobile Apps and Azure using Change Tracking API-4.png

 

 

The server is sending us only a Diff data set, which contains all the changes we need to apply locally, to move the version we have, 123, to become the same as the current data, which is represented by the new version number, 201.

 

Within the Data section, there is a new element, _$operation_, that tell us if that data must be Inserted, Updated, or Deleted, so that, if we'll apply all changes to local data (version 123) it will become the same as the current data on server (version 201).

 

It's up to us to apply the received data, with the specified operations, to our local data set, as how those changes will be applied depends on the technology we decided to use to store our data locally.

 

Wouldn't it be nice...

...if the generation of the JSON, the decision if a row must be inserted, updated or delete, can be done by the database for us? We just pass the starting version to the database, which it will check the difference against the current version and...well, done.

 

Yes, it would be nice. No, better, it would be amazing...because figuring out what are the changes to be sent to each different user/device is really not a simple task.

 

Let me explain why with a simple example: for UserA/Device1, it might be that some data doesn't even need to be sent at all, because, since its last sync, that data was inserted and then deleted, so there is no point in sending it at all. But maybe for UserA/Device2 things are different. Let's say it was synced after the insert but before the subsequent delete of the same document...as you can guess, UserA/Device2 only needs to be acknowledged of the delete operation.

 

Now imagine a lot of users and a lot of devices. How time consuming doing something like that could be? Yeah, very time consuming.

 

Well, luckily for us Azure SQL does exactly this. Change Tracking is an amazing technology that will make everything I just explained as easy as:

 

select 
ct.SYS_CHANGE_OPERATION as '$operation',
ct.Id,
ts.RecordedOn,
ts.[Type],
ts.Steps,
ts.Distance
from
dbo.TrainingSession as ts
right outer join
changetable(changes dbo.TrainingSession, @fromVersion) as ct on ct.[Id] = ts.[id]

 

The changetable operator will take care of everything for you, exactly as we dreamed of. Just pass in the version you want to sync from, and it will give you all the operations you need to do to sync with the current version, whatever it is.

 

Now, we're all developers here....so we really don't want to deal with tables, rows and all that stuff. How to turn that into JSON?

 

We learned how to do that in the previous articles. This time is a bit (just a bit, I promise!) more complex as we want to create a JSON like we discussed before, and we don't want to use the JSON as it comes out from Azure SQL.

 

Azure SQL allows to define the JSON in exact shape you need, thanks to FOR JSON PATH:

 

select
@curVer as 'Metadata.Sync.Version',
'Diff' as 'Metadata.Sync.Type',
[Data] = json_query((
select
ct.SYS_CHANGE_OPERATION as '$operation',
ct.Id,
ts.RecordedOn,
ts.[Type],
ts.Steps,
ts.Distance
from
dbo.TrainingSession as ts
right outer join
changetable(changes dbo.TrainingSession, @fromVersion) as ct on ct.[Id] = ts.[id]
for
json path
))
for
json path, without_array_wrapper

Isn't that amazing? Just think to how many hours of work you have just saved!

 

See it in action!

If you are interested and want to see that in action yourself, you can find a working sample where:

 

https://github.com/Azure-Samples/azure-sql-db-sync-api-change-tracking

 

you'll be able to deploy it in minutes.

 

Sync Mobile Apps and Azure using Change Tracking API-2.png

 

Everything is done in C#, but doing it in Python should be quite simple, as you can start from here:

Building REST API with Python, Flask and Azure SQL and make the few required changes.

 

Enjoy!

10 Comments
Copper Contributor

A very complete and informative article as always, keep them coming :happyface:

Video and Illustrations are definitely an added value

Copper Contributor
Microsoft

Hi @gpartida - the method that Davide posted would be preferable right now because Azure Mobile App Services is deprecated. If you have a solution already set up with it, it will continue to work, and you can file issues on the GitHub repo for it for bugs.

Copper Contributor

This is a great article and very promising, thanks for posting. 

 

I would be interested to know if anyone has completed any work on the mobile side of this equation? Also it would be good to point out in the article, that this is only a one directional sync, nothing is tracked on the client side to send back to the server.

 

I would also be interested to know in the article what additional cost we can expect to turn this feature on for sql azure??

 

Thanks!!

 

Microsoft

Hi @rfrick81 

 

I'm currently working on an article & sample for a Xamarin app. It'll be posted on devblogs.microsoft.com/xamarin hopefully in the next week.

 

@damauri - can you speak to whether there's any cost for turning on change tracking?

Copper Contributor

@mattsoucoup That is great news. I was going to spend some time rolling my own, but would love to see what you came up with first. Thanks for letting me know you are working on something. Appreciate it!!!

Microsoft

@rfrick81 there are no additional costs to use Change Tracking. Enjoy :)

Copper Contributor

Thank you both @damauri and @mattsoucoup! I have my server side code working very well. I like how there is no black box of code or additional dll's to add, and you can see exactly what is going on. I also like the json that gets past into the proc, very slick. I will certainly be using that technique in other places to future proof adjustments to stored procedures. Our database is setup in a multi tenant environment so having full control allows us to not only filter the data by tenant but also by user if we need to in the future. @mattsoucoup looking forward to seeing what you have setup on the client side since we will be using Xamarin for our mobile development. Cheers to you both!

 

-Ron

Copper Contributor

@mattsoucoup Hey Matt! Hope all is well in these crazy days. Any new development on this? I'm at a point that I have to kick off my mobile project and this will be a big part of how the apps works. Offline first. :) Cheers!

Copper Contributor

Davide Mauri's article on syncing mobile apps with Azure through the Change Tracking API highlights the importance of effective integration between cloud and mobile technologies. It underscores the value of custom mobile app development in creating flexible and scalable solutions. Mauri's approach enables developers to build applications that easily adapt to changes and ensure seamless data synchronization between devices and the cloud, key to developing high-performance and user-centric mobile applications.

Version history
Last update:
‎Nov 09 2020 09:41 AM
Updated by: