What I meant was that a client is of of sync when a client has a different value in DB (to be more precise different value in a column) for given resource ID than the master DB on server.
Also to clarify it a little bit. I am using HTTP transport so I can send only messages from GCM, no upstream messages from clients.
My initial thought was that I could send messages via GCM carrying a payload with new values. So the server is authoritative and whatever he sends clients accept. And clients would send via a web service their delta changes performed on columns e.g. (resource ID, column index in DB, current value on client, delta change made on the client).
So for example, client A sends values (R100, 3, 10, -1). Server then compares those values against master DB. If value for resource R100 in column with index 3 is 10, then the server changes it to 9 and notifies other clients via GCM with a message carrying payload (R100, 3, 9) with a collapse key consisting of resource ID_column index => collapse key R100_3.
This would ensure that if a client is offline and gets back online it will receive always the latest value for given column and just updates it in its DB.
But still as you mentioned I would have to do some sort of ordering of messages on the client in case ADD operation is received after UPDATE for the same resource ID. Or server will have to resend all operations since last sync, etc. What quite complicates implementation & testing and I don't have much time now for that.
Moreover, using the collapse key this way I could sync only four columns as GCM allows only up to four different collapse keys per client what is unfortunately not sufficient in my scenario.
But I will use GCM I like it :) But I will take the standard approach for now.
I will use messages with collapse key only containing the resource ID. So GCM will notify clients of (any) changes made on particular resource in master DB.
And clients will then store received resource IDs and call a web service with those IDs to fetch current data from server.
This way it will be pretty easy to implement on the client and on the server. And it will be reliable. And clients will fetch only resources with IDs which have changed.