Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / realtime

Development of mobile applications on Backend as a Service platforms

0.00/5 (No votes)
2 Jul 2015CPOL6 min read 13K  
Comparison of Firebase and SynergyKit while developing chat application

Introduction

Realtime applications are becoming even more popular these days, but the development of such applications is not an easy process. Which is the reason why new realtime platforms are being born. They will make realtime application implementation much easier. Developers need no longer worry about synchronization of data with server and on top of it they can save up to 80% of their time while developing products and focus more on UX/UI.


The world’s most famous realtime platform is most probably Firebase which has more than 200 000 registered users as of today. SynergyKit, on the other hand, is name of new evolving platform of czech company Letsgood.com (Etnetera Group). At the moment is SynergyKit in public beta mode.

SynergyKit or Firebase?

In order to compare these two products, I will take a look at very frequent Use Case which is part of a chat application. The application displays realtime messages from users and they are sent using push notification if application is not in foreground. You can register and login via Facebook profile.


Sample application with source codes can be found at GitHub.

Application Screenshots

The look of application is built on sample application for Synergit and slightly modified.

Image 1Image 2Image 3Image 4

Instalation

SynergyKit

SynergyKit SDK for Android minimum requirement is version Android SDK 14.

Into file build.gradle in element dependencies is needed to add following dependency.

VBScript
dependencies {
   ...
   compile 'com.letsgood:synergykit-sdk-android:2.1.7'
}

Since the application uses internet access, it is necessary to ask Android for right to use internet. This can be done in file AndroidManifest.xml, where you need to put following code into manifest element.

XML
<manifest ... >
<uses-permission android:name="android.permission.INTERNET" />
...
</manifest>

Next you need to initialize SynergyKit SDK before you can use it. I recommend to get it done by onCreate method from Application class.

Java
public void onCreate() {
   super.onCreate();

   Synergykit.init(APPLICATION_TENANT, APPLICATION_KEY);
   ...
}

Firebase

Firebase SDK for Android requirement minimum is Android SDK 10.

Into file build.gradle is needed to add the following dependency and packigingOptions.

VBScript
android {
   ...
   packagingOptions {
      exclude 'META-INF/LICENSE'
      exclude 'META-INF/LICENSE-FIREBASE.txt'
      exclude 'META-INF/NOTICE'
   }
}
dependencies {
   ...
   compile 'com.firebase:firebase-client-android:2.3.0'
}

SInce the application uses internet access, it is needed to ask Android for right to use internet. This can be done in file AndroidManifest.xml, where you insert this code to manifest element.

XML
<manifest ... >
   <uses-permission android:name="android.permission.INTERNET" />
   ...
</manifest>

Before its first use, Firebase needs Context to run, I recommend onCreate method from Application class.

Java
public void onCreate() {
   super.onCreate();

   Firebase.setAndroidContext(this);
   ...
}

User login

A user will login via Facebook, name from Facebook will be saved and used for sending messages. For each user information about their online status will be saved.

SynergyKit

SDK doesn't support getting a name from Facebook AccessToken, therefore you need to get this name before login. This can be done through GraphRequest. A name of user will be saved in a variable Name.

Java
GraphRequest request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
   @Override
   public void onCompleted(JSONObject object, GraphResponse response) {
      String name = null;
      try {
         name = object.getString("name"); // user's name on Facebook
      } catch (JSONException e) {
         e.printStackTrace();
      }
   }
});
Bundle parameters = new Bundle();
parameters.putString("fields", "name");
request.setParameters(parameters);
request.executeAsync();

In parameter User will be delivered SynergyKitUser, where will be set name, online status and data will be saved.

Java
Synergykit.linkFacebook(user, synergykitFacebookAuthData, new UserResponseListener() {
   @Override
   public void doneCallback(int statusCode, SynergykitUser user) {
      // login successful
   }
   @Override
   public void errorCallback(int statusCode, SynergykitError errorObject) {
      // login error
   }
});

Firebase

Login via Firebase is easier. You dont need to get name of user through GraphRequest. This solves Firebase SDK for Android itself.

Java
private Firebase firebase;
...
firebase = new Firebase("https://<APP_URL>.firebaseio.com"); // onCreate init
...
firebase.authWithOAuthToken("facebook", accessToken.getToken(), new Firebase.AuthResultHandler() {
   @Override
   public void onAuthenticated(AuthData authData) {
      // login successful
      setOnline(true); // my method described below
   }
   @Override
   public void onAuthenticationError(FirebaseError firebaseError) {
      // login error
   }
});

But this is only user login not saving of a user. For saving I will use function which changes online status of user on server. The function is explained below in Online Status Setup.

Online Status Setup

A user with displayed chat is online. When the application is overlapped by another application, display goes off or a user closes the application, it will switch to offline. Those functions call onResume and onPause so they set the right status.  

SynergyKit

The function described below sets online status to user. Parameter online is user’s status. Second parameter paralleMode will cause that this operation will run asynchronously.

private void setOnline(boolean online, boolean parallelMode) {
   if (user == null) return;
   user.setOnline(online);
   Synergykit.updateUser(user, new UserResponseListener() {
      @Override
      public void doneCallback(int statusCode, SynergykitUser synergykitUser) {
         user = (SKUser) synergykitUser; // user successfully updated
      }
      @Override
      public void errorCallback(int statusCode, SynergykitError synergykitError) {
         // user update failed
      }
   }, parallelMode);
}

Firebase

The function described below sets online status to user. If user doesnt exist, it will create him. Firebase uses JSON data so here is used a map.

Java
private void setOnline(boolean online) {
   Map<String, Object> map = new HashMap<>();
   map.put("name", userName); // user's name
   map.put("online", online); // online status
   firebaseUsers.child("" + uId).setValue(map); // create or override previous values
}

Messaging

Messaging is solved by adding a message into collection for both platforms, where application listens to changes which are received through websockets.

SynergyKit

Class containing all necessary attributes was created and for needs of SynergyKit expands SynergykitObject. The following code adds a message to collection.

Java
Synergykit.createRecord(COLLECTION_MESSAGES, message, new ResponseListener() {
   @Override
   public void doneCallback(int statusCode, SynergykitObject synergykitObject) {
      // message sent
   }
   @Override
   public void errorCallback(int statusCode, SynergykitError synergykitError) {
      // sending message failed
   }
}, true);

Firebase

Class containing all necessary attributes was created. The following code adds a message to collection.

Java
firebaseMessages.push().setValue(message, new Firebase.CompletionListener() {
   @Override
   public void onComplete(FirebaseError firebaseError, Firebase firebase) {
      if (firebaseError != null) {
         // sending message failed
      } else {
         // message sent
      }
   }
});

Receiving messages

Receiving messages for both platforms is solved by listening for event adding to collection. Application will display last 100 messages.

SynergyKit

The following code gets last 100 records from messages collection.

Java
SynergykitUri synergyKitUri = UriBuilder.newInstance()
 .setResource(Resource.RESOURCE_DATA) // setting resource to data
 .setCollection(COLLECTION_MESSAGES) // setting collection to messages
 .setOrderByDesc("createdAt") // sorting by "createdAt"
 .setTop(prevMessageCount) // top 100 messages
 .build();
SynergykitConfig config = SynergykitConfig.newInstance()
 .setParallelMode(true)
 .setType(SKMessage[].class) // setting result type
 .setUri(synergyKitUri); // setting URI created above
Synergykit.getRecords(config, new RecordsResponseListener() {
   @Override
   public void doneCallback(int statusCode, SynergykitObject[] synergykitObjects) {
      SKMessage[] messages = (SKMessage[]) synergykitObjects; // posledních 100 zpráv sestupně
   }
   @Override
   public void errorCallback(int statusCode, SynergykitError synergykitError) {}
});

The following code will register socket for listening for event created.

Java
// listening on socket for event created in collection messages
Synergykit.onSocket(EVENT_CREATED, COLLECTION_MESSAGES, new SocketEventListener() {
   @Override
   public void call(Object... objects) { 
      String data = objects[0].toString(); // JSON data
      final SKMessage message = GsonWrapper.getGson().fromJson(data, SKMessage.class); // get message
   }
   @Override
   public void subscribed() {}
   @Override
   public void unsubscribed() {}
});

Synergykit.connectSocket();

Firebase

Query is used for filtration and cutting down the number of messages. ChildEventListener enables listening for changes.

Java
Query query = firebaseMessages.orderByChild("timestamp").limitToLast(prevMessageCount);
query.addChildEventListener(new ChildEventListener() {
   @Override
   public void onChildAdded(DataSnapshot dataSnapshot, String s) {
      if (dataSnapshot == null) return; // no data received
      FBMessage message = dataSnapshot.getValue(FBMessage.class); // get message
   }

   @Override
   public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
   @Override
   public void onChildRemoved(DataSnapshot dataSnapshot) {}
   @Override
   public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
   @Override
   public void onCancelled(FirebaseError firebaseError) {}
});

Push Notifications

Push notification will be received and displayed when a user is not on chat screen. Push notification will have form “Sender: message”  and will play a default notification sound while receiving. Information regarding Push Notifications from GCM.

SynergyKit

The prerequisite is having created an application in Google Console. Into application settings in SynergyKit is necessary to write down so called API key GCM, which can be done in bookmark Settings->Android GCM.

New dependency has to be added into file build.gradle.

VBScript
dependencies {
   ...
   compile 'com.google.android.gms:play-services-gcm:7.5.0'
}

Registration ID is acquired by registration to GCM service.

Java
regid = gcm.register(SENDER_ID);

Registration ID acquired earlier has to be saved on server which will be sending out Push Notifications. SynergyKit saves this information to an instance of the class SynergyKitPlatform. Class SynergyKitPlatform is part of class SynergykitUser or its follower.

Java
if (platform == null) { // create new platform
   SynergykitPlatform platform = new SynergykitPlatform(regid); // passing gcm registration id
   Synergykit.addPlatform(platform, new PlatformResponseListener() {
      @Override
      public void doneCallback(int statusCode, SynergykitPlatform platform) {
         // add successful
      }
      @Override
      public void errorCallback(int statusCode, SynergykitError errorObject) {
         // add failed
      }
   }, true);
} else if (!platform.getRegistrationId().equals(regid)) { // id is different
   platform.setRegistrationId(regid);
   Synergykit.updatePlatform(platform, null, true); // update platform without listener
}

Cloud code enables to run the code on the server side. From a device it is possible to turn on or set automatic turning on in event at collection. Code is written in JavaScript to browser IDE, where it can be also debugged.

I have set up trigger to event “created” in collection messages, therefore Cloud code will be called after receiving a message. The following Cloud code gets all users having set up attribute online to false and will send them notification.

Java
var queryOfflineUsers = Synergykit.Query(Synergykit.User()); // begin query
// gets all users with online state set to false
queryOfflineUsers.where().attribute("online").isEqualTo(false).find({
   success: function(offline_users, code) {
      if (code == 200) {
         var notification = Synergykit.Notification(offline_users); // creating notification with all offline users
         var text = parameters.name + ': ' + parameters.text; // ziskani textu notifikace
         notification.set("alert", text); // pridani textu k notifikaci
         notification.send({ // odeslani notifikace
            success: function(result, statusCode) {
               callback({
                  result: 'success',
                  offline_users: offline_users
               });
            },
            error: function(error, statusCode) {
               callback;
            }
         });
      } else {
         callback;
      }
   },
   error: callback
});

Notification has been sent to all users, yet the application is not receiving them. It is needed to implement receiving of notification from GCM in Android.

By the following code I have requested rights in manifest.

VBScript
<manifest ... >
   <uses-permission android:name="android.permission.GET_ACCOUNTS" />
   <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
   <uses-permission android:name="android.permission.WAKE_LOCK" />
   <permission
      android:name="<PACKAGE_NAME>.permission.C2D_MESSAGE"
      android:protectionLevel="signature" />
   <uses-permission android:name="<PACKAGE_NAME>.permission.C2D_MESSAGE" />
</manifest>

GcmReceiver receives messages from GCM and has to be added to manifest.

XML
<manifest ... >
   <application ... >
      ...
      <receiver
         android:name="com.google.android.gms.gcm.GcmReceiver"
         android:exported="true"
         android:permission="com.google.android.c2dm.permission.SEND">
         <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
         </intent-filter>
      </receiver>
      ...
   </application>
</manifest>

MyGcmListenerService is a service which will receive messages from receiver and subsequently create notification. Service has to be added to manifest, too.

XML
<manifest ... >
   <application ... >
      ...
      <service
         android:name="<PACKAGE_NAME>.MyGcmListenerService"
         android:exported="false">
         <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
         </intent-filter>
      </service>
      ...
   </application>
</manifest>

Class MyGcmListenerService displays notification to user when he accepts it from GcmReceiver.

Java
public class MyGcmListenerService extends GcmListenerService {
   @Override
   public void onMessageReceived(String from, Bundle data) {
      String message = data.getString("alert"); // get text of message
      sendNotification(message);
   }
   private void sendNotification(String message) {
      NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
      ... // setup notification
      NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
      notificationManager.notify(0 /* notification ID */, notificationBuilder.build());
   }
}

Firebase

Firebase doesn’t support sending push notifications and its implementations is not easy. There many tutorials on internet, though, which can help solve this situation by your own server application.

Conslusion

For this particular application is better to use SynergyKit. Firstly, for creating push notification on Firebase platform you need to use product of third party. Secondly, SynergyKit enables moving parts of codes to server and by doing this devices can last longer. Server part can be modified in browser and these changes don’t require updating of application. Both platforms offer simple user login, reading and writing data.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)