The primary function of my app is to share lists between people. Until recently anyone could share any list without consent from the receiver. Doing this opens up opportunities for people to spam shared lists on people they don’t know. Quite frankly, even if you’d know the person sharing a list with you , it would be nice with an heads up before receiving said list. This called for new functionality in form of an invitations system.
In order to do this I created a new class called ListInvitation (clever name?!). This class represents the invites sent from one user to other users.The class consists of six attributes:
- List name
- Sender of the invitation
- Receiver of the invitation
- Invitation status (handled/not handled)
- Creation date
- List Id
I also needed to create a new DynamoDB table for this purpose in order for users to fetch them. When creating a new table in DynamoDB you have to specify a primary key, which in this case could have been an ListInvitation unique identifier of sorts. But since I had to couple invitations with users I decided to create what is kind of a composed primary key. What I mean with this is that the primary key is composed of 2 different attributes. In this case the attributes were the list id of the list to share and the receiver of the shared list. Together these attributes is considered unique and act as the tables primary key.
When mapping a Java class to a DynamoDB table notations are used. The notations are used by the DynamoDBObjectMapper class when serializing requested objects from the databases to Java objects. A simple notation mapping an attribute looks like :
These notations are needed at each attribute to be mapped, though there are annotations such as @DynamoDBIgnore which will tell the DynamoDBObjectMapper to ignore a specific attribute.
When finished with creating the table and the model class, I then created a service that would use the Android AWS Sdk to fetch any invitations not already answered. This is done each time at app startup, manual refresh of data and between activity transitions.
To fetch all invitations we first need to create a query object. This object represents what attributes the DynamoDBObjectMapper should refer to when looking up invitations. This time I’m sending through the current app user, which will create a temporary object with only the receiver attribute. It could be seen as building from an empty shell to fetch all objects matching the receiver attribute. The method query from DynamoDBObjectMapper takes a class template and a DynamoDBQueryExpression and will return a List of the specified type (ListInvitation). Upon success this will fire an event in an EventBus channel back to the Activity originally calling the service. Right now I’m in the process of looking into possible errors that can occur when fetching data from DynamoDB, and will probably make a blog post in the future about the subject.
The screenshots below show the final results of receiving a notification of a new invitation and the invitation itself (UI in progress still on this one though). Continuing on I will probably work more on errorhandling when communicating with DynamoDB, and will as mentioned before make a post about that soon.