Kotlin Firebase Cloud Messaging – How to Send Upstream Messages | Android

In some Firebase Cloud Messaging tutorials, we have known way to receive Messages. Today we’re gonna look at how to send Upstream Messages from an Android Client App.

Related Post: Firebase Cloud Messaging – XMPP Server example to receive Upstream Messages | Spring Integration

I. Way to do

0. Add Firebase to Android App

Follow these steps.

Open Gradle file to check what happens, we can see that some code has been added:
build.gradle (project-level):

buildscript {
    // ...
    dependencies {
        // ...
        classpath 'com.google.gms:google-services:3.1.0'
    }
}

build.gradle (App-level):

dependencies {
    // ...
    implementation 'com.google.firebase:firebase-messaging:11.0.4'
}

apply plugin: 'com.google.gms.google-services'

1. Get Sender ID

Go to Settings of your Firebase Project in Firebase Console to get Sender ID.

2. Send an Upstream Message

Using FirebaseMessaging.send() method:

val fm = FirebaseMessaging.getInstance()

val message = RemoteMessage.Builder(SENDER_ID + "@gcm.googleapis.com")
        .setMessageId(Integer.toString(random.nextInt(9999)))
        .addData(edt_key1.text.toString(), edt_value1.text.toString())
        .addData(edt_key2.text.toString(), edt_value2.text.toString())
        .build()

fm.send(message)

3. Handle Callbacks

We can implement onMessageSent() and onSendError() to check the status of Upstream Messages in the class that extends FirebaseMessagingService:

class MyFCMClass : FirebaseMessagingService() {

    override fun onMessageSent(msgId: String?) {
        // ...
    }

    override fun onSendError(msgId: String?, e: Exception?) {
        // ...
    }
}

onSendError(): returns a SendException with an error code:
.ERROR_INVALID_PARAMETERS: Message was sent with invalid parameters.
.ERROR_SIZE: Message exceeded the maximum payload size.
.ERROR_TOO_MANY_MESSAGES: App has too many pending messages so this one was dropped.
.ERROR_TTL_EXCEEDED: Message time to live (TTL) was exceeded before the message could be sent.
.ERROR_UNKNOWN: Unknown error.

To optimize network usage, these acknowledgement may not be immediate for each message. You may receive callback after about 10 messages.

4. Add Service to Android Manifest

For Firebase Service:

<application
    ...
   <activity android:name=".MainActivity">
       ...
   </activity>

   <!-- Firebase Service -->
   <service android:name=".MyFCMClass">
       <intent-filter>
           <action android:name="com.google.firebase.MESSAGING_EVENT" />
       </intent-filter>
   </service>
</application>

II. Practice

1. Goal

We will build an Android App that can:
– send Message Data from input Text upstream to Firebase when clicking on the Button.
– handle onMessageSent() and onSendError() Callbacks.

kotlin-fcm-upstream-message-goal

2. Technology

– Gradle 3.0.1
– Android Studio 3.x
– Firebase Android SDK 11.x

3. Project Structure

kotlin-fcm-upstream-message-structure

4. Step by step

4.1 Create Android Project & Add Firebase Cloud Messaging

– Generate new Android Project with package com.javasampleapproach.kotlin.firebase.fcm.
– Follow these steps to add Firebase to Android Project.

4.2 Activity for sending Upstream Messages

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:paddingLeft="16dp"
    android:paddingRight="16dp">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/edt_key1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="7"
            android:inputType="text"
            android:text="Key 1" />

        <EditText
            android:id="@+id/edt_value1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="text"
            android:text="Value 1" />

    </LinearLayout>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/edt_key2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="7"
            android:inputType="text"
            android:text="Key 2" />

        <EditText
            android:id="@+id/edt_value2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="text"
            android:text="Value 2" />

    </LinearLayout>


    <Button
        android:id="@+id/btn_upmessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="UPSTREAM MESSAGE" />

</LinearLayout>
package com.javasampleapproach.kotlin.firebase.fcm

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import kotlinx.android.synthetic.main.activity_main.*
import com.google.firebase.messaging.FirebaseMessaging
import java.util.*
import com.google.firebase.messaging.RemoteMessage

class MainActivity : AppCompatActivity() {

    private val TAG = "JSA-FCM"
    private val SENDER_ID = "xxxxxxxxxxxx"
    private val random = Random()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        btn_upmessage.setOnClickListener {
            val fm = FirebaseMessaging.getInstance()

            val message = RemoteMessage.Builder(SENDER_ID + "@gcm.googleapis.com")
                    .setMessageId(Integer.toString(random.nextInt(9999)))
                    .addData(edt_key1.text.toString(), edt_value1.text.toString())
                    .addData(edt_key2.text.toString(), edt_value2.text.toString())
                    .build()

            if (!message.data.isEmpty()) {
                Log.e(TAG, "UpstreamData: " + message.data)
            }

            if (!message.messageId.isEmpty()) {
                Log.e(TAG, "UpstreamMessageId: " + message.messageId)
            }

            fm.send(message)
        }
    }
}

4.3 Create class for handling callbacks

Inside com.javasampleapproach.kotlin.firebase.fcm package, create MyFCMClass:

package com.javasampleapproach.kotlin.firebase.fcm

import android.util.Log

import com.google.firebase.messaging.FirebaseMessagingService

class MyFCMClass : FirebaseMessagingService() {

    private val TAG = "JSA-FCM"

    override fun onMessageSent(msgId: String?) {
        Log.e(TAG, "onMessageSent: " + msgId!!)
    }

    override fun onSendError(msgId: String?, e: Exception?) {
        Log.e(TAG, "onSendError: " + msgId!!)
        Log.e(TAG, "Exception: " + e!!)
    }
}

4.4 Add Firebase Service to AndroidManifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.javasampleapproach.kotlin.firebase.fcm">

    <application
        ...
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Firebase Service -->
        <service android:name=".MyFCMClass">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
    </application>

</manifest>

4.5 Run & Check result

– Use Android Studio, build and Run your Android App.
– Fill Edit Text in the App UI, then click on UPSTREAM MESSAGE about 10 times:
kotlin-fcm-upstream-message-goal

– Logcat in Android Studio:
kotlin-fcm-upstream-message-result

III. Source code

Kotlin-FCM-send-upstream-message

0 0 votes
Article Rating
Subscribe
Notify of
guest
1.4K Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments