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
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:
– 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