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

0.1 Add Firebase Config file

Follow this guide to generate google-services.json file and move it into your Android App root directory. You don’t need to get SHA-1 Key in this example.

0.2 Add dependencies

build.gradle (project-level):


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

build.gradle (App-level):


dependencies {
    // ...
    compile 'com.google.firebase:firebase-core:11.0.2'
    compile 'com.google.firebase:firebase-messaging:11.0.2'
}

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

0.3 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>

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:


FirebaseMessaging fm = FirebaseMessaging.getInstance();
fm.send(new RemoteMessage.Builder(SENDER_ID + "@gcm.googleapis.com")
  .setMessageId(MESSAGE_ID)
  .addData("key-1", "value-1")
  .addData("key-2", "value-2")
  .build());

3. Handle Callbacks

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


public class MyFCMClass extends FirebaseMessagingService {

    @Override
    public void onMessageSent(String msgId) {
        // ...
    }

    @Override
    public void onSendError(String msgId, Exception e) {
        // ...
    }
}

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.

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.

2. Technology

– Gradle 2.3.3
– Android Studio 2.x
– Firebase Android SDK 11.x

3. Project Structure

firebase-cloud-messaging-upstream-messages-structure

4. Step by step

4.1 Create Android Project

– Generate new Android Project with package com.javasampleapproach.fcm.
build.gradle (project-level):


buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        classpath 'com.google.gms:google-services:3.1.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

build.gradle (App-level):


android {
    compileSdkVersion 25
    buildToolsVersion "25.0.0"
    defaultConfig {
        applicationId "com.javasampleapproach.fcm"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

        debug {
            debuggable true
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.1', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.google.firebase:firebase-core:11.0.2'
    compile 'com.google.firebase:firebase-messaging:11.0.2'
    testCompile 'junit:junit:4.12'
}

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

4.2 Create Firebase Project & Add Firebase Config file

– Follow this guide to generate google-services.json file and move it into your Android App root directory. You don’t need to have SHA-1 Key in this example, just leave it blank.

– Make sure that package_name in google-services.json has a correct value according to:
+ applicationId in build.gradle (App-level).
+ package in AndroidManifest.xml.
In this case, it is com.javasampleapproach.fcm.

4.3 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.fcm;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.google.firebase.messaging.FirebaseMessaging;
import com.google.firebase.messaging.RemoteMessage;

import java.util.Map;
import java.util.Random;

public class MainActivity extends AppCompatActivity {

    private Button btn_upmessage;
    private EditText edt_key1;
    private EditText edt_value1;
    private EditText edt_key2;
    private EditText edt_value2;

    private final String TAG = "JSA-FCM";
    private final String SENDER_ID = "xxxxxxxxxx";
    private Random random = new Random();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        edt_key1 = (EditText) findViewById(R.id.edt_key1);
        edt_key2 = (EditText) findViewById(R.id.edt_key2);
        edt_value1 = (EditText) findViewById(R.id.edt_value1);
        edt_value2 = (EditText) findViewById(R.id.edt_value2);

        btn_upmessage = (Button) findViewById(R.id.btn_upmessage);

        btn_upmessage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FirebaseMessaging fm = FirebaseMessaging.getInstance();

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

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

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

                fm.send(message);
            }
        });

    }
}

4.4 Create class for handling callbacks

Inside com.javasampleapproach.fcm package, create MyFCMClass:


package com.javasampleapproach.fcm;

import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;

public class MyFCMClass extends FirebaseMessagingService {

    private final String TAG = "JSA-FCM";

    @Override
    public void onMessageSent(String msgId) {
        Log.e(TAG, "onMessageSent: " + msgId);
    }

    @Override
    public void onSendError(String msgId, Exception e) {
        Log.e(TAG, "onSendError: " + msgId);
        Log.e(TAG, "Exception: " + e);
    }
}

4.5 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.fcm">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <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.6 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:
firebase-cloud-messaging-upstream-messages-ui

– Logcat in Android Studio:


07-12 10:38:10.463 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamData: {Key 1=Value 1, Key 2=Value 2}
07-12 10:38:10.463 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamMessageId: 6442
07-12 10:38:13.343 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamData: {Key 1=Value 1, Key 2=Value 2}
07-12 10:38:13.343 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamMessageId: 925
07-12 10:38:13.913 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamData: {Key 1=Value 1, Key 2=Value 2}
07-12 10:38:13.913 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamMessageId: 1815
07-12 10:38:14.353 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamData: {Key 1=Value 1, Key 2=Value 2}
07-12 10:38:14.353 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamMessageId: 2452
07-12 10:38:14.733 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamData: {Key 1=Value 1, Key 2=Value 2}
07-12 10:38:14.733 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamMessageId: 6265
07-12 10:38:15.223 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamData: {Key 1=Value 1, Key 2=Value 2}
07-12 10:38:15.223 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamMessageId: 9679
07-12 10:38:15.693 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamData: {Key 1=Value 1, Key 2=Value 2}
07-12 10:38:15.693 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamMessageId: 8643
07-12 10:38:16.383 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamData: {Key 1=Value 1, Key 2=Value 2}
07-12 10:38:16.383 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamMessageId: 6075
07-12 10:38:16.853 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamData: {Key 1=Value 1, Key 2=Value 2}
07-12 10:38:16.853 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamMessageId: 5607
07-12 10:38:17.483 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamData: {Key 1=Value 1, Key 2=Value 2}
07-12 10:38:17.483 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamMessageId: 3424
07-12 10:38:18.653 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamData: {Key 1=Value 1, Key 2=Value 2}
07-12 10:38:18.653 25106-25106/com.javasampleapproach.fcm E/JSA-FCM: UpstreamMessageId: 8681
07-12 10:38:18.773 25106-30312/com.javasampleapproach.fcm E/JSA-FCM: onMessageSent: 6442
07-12 10:38:18.783 25106-30313/com.javasampleapproach.fcm E/JSA-FCM: onMessageSent: 925
07-12 10:38:18.793 25106-30313/com.javasampleapproach.fcm E/JSA-FCM: onMessageSent: 1815
07-12 10:38:18.803 25106-30314/com.javasampleapproach.fcm E/JSA-FCM: onMessageSent: 2452
07-12 10:38:18.813 25106-30315/com.javasampleapproach.fcm E/JSA-FCM: onMessageSent: 6265
07-12 10:38:18.813 25106-30316/com.javasampleapproach.fcm E/JSA-FCM: onMessageSent: 9679
07-12 10:38:18.823 25106-30317/com.javasampleapproach.fcm E/JSA-FCM: onMessageSent: 8643
07-12 10:38:18.833 25106-30317/com.javasampleapproach.fcm E/JSA-FCM: onMessageSent: 6075
07-12 10:38:18.843 25106-30318/com.javasampleapproach.fcm E/JSA-FCM: onMessageSent: 5607
07-12 10:38:18.843 25106-30319/com.javasampleapproach.fcm E/JSA-FCM: onMessageSent: 3424
07-12 10:38:18.853 25106-30319/com.javasampleapproach.fcm E/JSA-FCM: onMessageSent: 8681

III. Source code

FCM-upstream-messages



By grokonez | July 12, 2017.

Last updated on April 28, 2021.



Related Posts


Got Something To Say:

Your email address will not be published. Required fields are marked *

*