Metadata provides an elegant mechanism for expressing and synchronizing contextual information about conversations. This is implemented as a free-form structure of string key-value pairs that is automatically synchronized among the participants in a conversation. Example use cases of metadata include:
- Setting a conversation title.
- Attaching dates or tags to the conversation.
- Storing a reference to a background image URL for the conversation.
The following demonstrates setting
metadata on a conversation:
Metadata metadata = Metadata.newInstance(); metadata.put("title", "My Conversation"); //You can nest metadata objects Metadata theme = Metadata.newInstance(); theme.put("background_color", "333333"); theme.put("text_color", "F8F8EC"); theme.put("link_color", "21AAE1"); metadata.put("theme", theme); metadata.put("created_at", "Dec, 01, 2014"); metadata.put("img_url", "/path/to/img/url"); //Assign the metadata to the conversation. //Pass in 'true' to merge the HashMaps (all old keys will be preserved and new values will be set) // or 'false' to replace the existing HashMap (all old key/pairs will be lost) mConversation.putMetadata(metadata, false);
For convenience and to facilitate the namespacing of information within metadata, values may be manipulated as key paths. A key path is a dot (.) delimited string that identifies a series of nested keys leading to a leaf value. For example, given the above metadata structure, an application could change the name of a participant via the following:
Applications can fetch metadata for a given conversation by accessing the public
metadata property on
Metadata current = mConversation.getMetadata(); mTitleTextView.setText((String)current.get("title"));
While this feature is both powerful and convenient, it is not designed to serve as a general purpose data store. It’s important to understand the intended use cases and limitations associated with the feature to ensure an ideal user experience. In particular, keep in mind that:
- Metadata is implemented with “last writer wins” semantics on a per key basis. This means that multiple mutations by independent users to a given key will result in a single stored value. No locking or other coordination is performed across participants.
- Metadata is automatically synchronized by each participant in the conversation. While Layer has gone to great lengths to implement metadata in a way that maximizes efficiency on the wire, it is important that the amount of data stored in metadata is kept to a minimum to ensure the quickest synchronization possible.
- Metadata values must be represented as strings. To ensure a satisfying user experience developers are strongly discouraged from storing any sort of binary data representation (including thumbnail images) via metadata. Instead, consider storing a URL or other reference to data that is transmitted out of band from synchronization.
- Metadata is limited to the storage of a maximum of 2KB of data under each key. Keys must be alphanumeric and may include hyphens and underscores, but cannot contain spaces. If your metadata key contains space you may run into issues if you try to query them. Nested structures may be used to facilitate efficient namespacing of content.
- There is not currently any limit enforced on the number of keys stored into the metadata structure. Because mutations are performed on a per key basis, it is advantageous to structure your data in such a way that smaller amounts of data are stored under a larger number of keys. Note that we may introduce a key limit in future versions.
- Mutable Conversation metadata should only be used to store information associated with the Conversation itself – not individual messages. As the number of metadata keys grow synchronization will take longer to complete. Because Conversations can be very long lived, performance can be severely impacted if dynamically computed keys (such as those built from message identifiers) are utilized.