Skygear Chat v1.5.0 release highlights: Build a offline-first chat app with v1.5.0


We have just released the iOS and the Android v1.5.0 chat SDK! Below is a summary of the highlighted updates. Please refer to the release note if you would like to get the whole list of the updates: iOS | Android.

1. You can now build an offline-first chat app with Skygear Chat!

When it comes to the user experience of a chat app, a good offline experience is indispensable: users want to read messages even when they are offline, and when they send a message offline, they want to re-send it easily when they go online.

The good news is, Skygear Chat now make building an offline-first chat app simple! Two new APIs handle everything you need for an offline chat app:

  1. fetchMessages: it cache message and return cached message so that you can display them when user is offline. In the iOS SDK, we have created a isCached flag in the callback to help you identify the operations from the cached store (i.e. isCached = True) and from the server (i.e. isCached = False). When you call fetchMessage, the callback will now be called twice. In the first time, the operation will return messages from the cached store. In the second time, the operation will return messages from the server. _In the Android SDK, we have created a onGetCachedResult callback function to get the messages from the cached store for you.
  2. fetchOutstandingMessageOperations: This new API allows you to get all the failed operations (including new message, edit messaage and delete message) and handle them depends on your business logic. Common way for offline chat app to handle it include automatically retry when user online again, or display the failed message (say with an exclamation mark) on screen so users can retry them manually.

The profiles of the chat participants are also stored in the cached store automatically. Learn more about it in the next section.

Special note to asset cache

This update only targets to cache message record. For asset-type messages (files, images, voice), you will only be getting the url of the asset. If you want to cache the asset itself, you have to handle it separately.

Special note to current Skygear Chat users

This new feature introduces breaking changes to the fetchMessages APIs. Documentation is already updated to reflect the new API changes. If you would like to stick with the older iOS or Android chat SDK version (i.e. < v1.5), you can still find the old docuementation and API reference here:

Guides | Android API reference

Sample codes

fetchMessage sample code in Swift:

    conversation: conversation,
    limit: 100,
    beforeTime: nil,
    order: nil,
    completion: { (messages, isCached, error) in
        if error != nil {
            print ("Messages cannot be fetched. " +

        if isCached {
            print ("Messages fetched from cache")

        print ("Messages fetched")

getMessage sample code in Java

Container skygear = Container.defaultContainer(getApplicationContext());
ChatContainer chatContainer = ChatContainer.getInstance(skygear);

    -1, // -1 as default limit
    null, // Date before
    new GetMessagesCallback() {
    public void onSuccess(@Nullable List<Message> messageList) {
        Log.i("MyApplication", "Messages Retrieved from server: " + messageList);

    public void onGetCachedResult(@Nullable List<Message> messageList) {
        Log.i("MyApplication", "Messages Retrieved from cache: " + messageList);

    public void onFail(@NonNull Error error) {
        Log.i("MyApplication", "Failed to get message list: " + error.getMessage());

2. Display user avatar and username in a chat interface with ease

Developers often need to display the profile of the participants in a chat interface (i.e. username, avatar). The new fetchParticipants API helps you get their profiles more easily. It accepts an array of participantIds (which you can get from a conversation object), and turns it into an array of user records. Similar to the fetchMessages API, it has an ‘isCached’ flag (iOS) or an onGetCachedResult callback function (Android) that helps you identify operations from the cached stores and the server.

Sample codes

fetchParticipants sample code in Swift:

        participantIDs: conversation.participantIds,
        completion: {[weak self] (result, isCached, error) in
            guard error == nil else {
            result.forEach({ (eachParticipantID, eachParticipant) in

getParticipants sample code in Java:

Container container = Container.defaultContainer(this);
ChatContainer chatContainer = ChatContainer.getInstance(container);
chatContainer.getParticipants(conversation.getParticipantIds(), new GetParticipantsCallback() {
    public void onGetCachedResult(Map<String, Participant> participantsMap) {
        for (Participant participant: participantsMap.values()) {
            Log.i("MyApplication", "Participant: " + participant.getRecord().get("username"));

    public void onSuccess(Map<String, Participant> participantsMap) {
        for (Participant participant: participantsMap.values()) {
            Log.i("MyApplication", "Participant from cache: " + participant.getRecord().get("username"));

    public void onFail(@NonNull Error error) {
        Log.e("MyApplication", "Failed to get participants: " + error.getMessage());

3. Customise the UI of the chat interface to match your app’s style

While UI Kit gives you an up and running conversation view right away, a lot of developers want to customize the UI to fit the style of their chat app. With SkygearChat v1.5.0, you can now customize the following components of the UI Kit:

  1. Title Bar
  2. Avatar (Outgoing)
  3. Message (Outgoing)
  4. Avatar (Incoming)
  5. Message (Incoming)
  6. Camera Button
  7. Text Input
  8. Voice Button

Here you can find the whole list of customisation properties: iOS | Android.

Other notes

You can read the release note here: iOS | Android

For those of you who want to upgrade your chat SDK to v1.5.0, beware of the following breaking changes:


  • fetchMessages added an ‘isCached’ flag in its callback


  • getMessages added a ‘onGetCachedResult’ callback function
  • onSucc renamed to onSuccess
  • class chatUser renamed to Participant

Leave us a comment or reach us on the community chat if you need support using the new features :grinning: