REST Server
I created a Rails server that contains :users
and associated :comments
. It is used as a backend API for an Android client. The exchange format to load and store data at the server is JSON. Here are the relevant migrations.
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.timestamps
end
end
end
...
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.references :users
t.string :subject
t.text :message
t.timestamps
end
end
end
All users have already been imported. Therefore, only read access is configured for the :users
resource. Thus, for :comments
it should be possible to add new entries. Here are the available routes.
user_comments GET /users/:user_id/comments(.:format) comments#index
POST /users/:user_id/comments(.:format) comments#create
new_user_comment GET /users/:user_id/comments/new(.:format) comments#new
user_comment GET /users/:user_id/comments/:id(.:format) comments#show
users GET /users(.:format) users#index
user GET /users/:id(.:format) users#show
Android client
On the client side I use a Service
with AsyncTasks
to download, parse and store users into a local SQLite database. A ContentProvider
delivers cached users to the UI. The user object downloaded from the server contains the unique id of the users
table. This should be useful when a new comment gets created on the client.
Scenario 1: Read comments
- Users are displayed in a list view on the Android client.
- A user item gets selected.
- The list activity creates an
Intent
which contains the user specific URI, e.g.content://com.example.myapp.provider/users/23
. - A user activity displays detail information about the user and associated comments.
- Cached comments get loaded via a
CursorLoader
. (1) - A synchronization process loads comments from the remote server. (2)
Scenario 2: Write comments
- A comment can be created from the user activity.
- The comment gets stored into the local database. (3)
- Stored comments are sychronized with the remote server. (2)
Headache questions
I marked the scenario steps that are associated with the following questions.
- How do I create a content URI for the comments being used with a
CursorLoader
in the user activity? Please mind, I only know the user URI at this point. - Can someone describe how I create a synchronization process? I am not sure if a SyncAdapter works here (never used it). Is the the synchronization process just a
Service
that on the one hand starts tasks to download, parse and store comments on the client and on the other hand loads, encodes and sends out comments to the server? - How does the content URI for a new comment look like? Is the
ContentProvider
for comments the same as for users? Is there only oneSQLiteOpenHelper
in the application?
The main problem I am struggling with is how to design the application? If you know of a better solution on how I should synchronize the users and their associated comments, you are very welcome.
Answers
Answers to question 1. and 3.
I extended the REST model as follows: The JSON hash returned for a comment now includes the id of the associated user. The same id is also included in the JSON hash for the user. Both objects are stored into the local database on the Android device. This allows me request comments for a specific user. I simply pass the server user id as WHERE
clause. The content URI for comments is not cascaded as I implied with my question. It is similar to the user content URI:
content://com.example.myapp.provider.commentsprovider/comments
Note, that I changed the authority part of the string. I decided to create separate content provider for users and comments.
One simple architecture is to always update things in the server first, sending posted comments to the server right away and from there pushing a notification through GCM to users that should request the updated comments list. The flow would look like:
"update_comments": "1"