I'm currently trying to develop an app with offline-first ability, however, the dependence between my data objects seems to be messing things up.
Say I have a profile
model where most of other data refers to, a task
model referring profile
, and a record
model referring to task
.
Since the connectivity between the client and server is not stable, the server should ensure the ultimate version of data should be consistent and same regardless of the order the update commands arrive. For example, [PUT(A)@time1, PUT(B(A))@time2, REMOVE(A)@time3] should result in a same version of data to [PUT(B(A))@time2, REMOVE(A)@time3, PUT(A)@time1].
This requirement of ability to handle out-of-order instructions reveals a potential problem that, a instruction may have an unmet dependency at the point it arrives at the server, for example the PUT(B(A))@time2
instruction is missing dependency of item A
and it's update in the database will result in a foreign-key error.
One naive solution I'd came up with is to upload the dependencies recursively in all of the instructions, and based on this naive solution, I've resolved the conflict problem by using updateAt
to merge same items, a syncAt
for fetch updated data, and a deleteAt
for soft-deletions.
A demo server and a demo client is made and proved the correctness without concurrency (see demo video).
However this seems to be a waste of bandwidth, and there are still other latent problems that have been coming to my mind, such as concurrency issues, cascade deletion issues, etc.
Is there a proper way to deal with such offline-first development without Firebase like SaaS providers (no access due to policy reasons)? I've searched for relevant topics but still confused, any help is appreciated.