I am new to Firebase and I am running into errors such as mismatch sender id and Authentication Error with HTTP status 401 when my Java application tries to send a notification/message using the client's Firebase token. Note that using Firebase Console, I am able to send the message to the client.
For the client app, I did the following:
- Cloned Firebase
messaging
quickstart app from here -- https://github.com/firebase/quickstart-android/tree/master/messaging -- which is already setup with Firebase dependencies and such. Loaded the cloned app inAndroid Studio
. - Using Firebase Console, created a new project called
My Notification Client
and added an app usingcom.google.firebase.quickstart.fcm
as the package name of the Android app. - Downloaded
google-services.json
file for the Android app added to the newly created project and copied it to themessaging/app/
folder and sync'd with Grade files from withinAndroid Studio
. - Created an emulator and ran the app from within
Android Studio
. When the app got loaded in the emulator, clicked theLog Token
button to capture the client's Firebase token in theAndroid Monitor
tab inAndroid Studio
. - Using Firebase Console, selected the newly created project
My Notification Client
, clicked theNotifications
link from the left pane, and sent a notification to the device by pasting the Firebase token captured in the previous step.
This worked great! The next step was to to use a separate simple Java application (which would eventually become a notification server) to send the notification to the client instead of using Firebase Console.
To accomplish this, I followed the steps outlined here -- https://firebase.google.com/docs/server/setup#prerequisites. Specifically, these are the steps that I performed:
- Created a new project called
My Notification Server
in Firebase Console. - Using
Settings > Permissions
in Firebase Console, created a new service account and downloaded theserviceAccountCredentials.json
file. - Created a new maven project in Eclipse and added the following dependencies in pom.xml:
<dependency>
<groupId>com.google.gcm</groupId>
<artifactId>gcm-server</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-server-sdk</artifactId>
<version>3.0.0</version>
</dependency>
Then, I extended
com.google.android.gcm.sender.Sender
to createFCMSender
and override protected methodgetConnection(String url)
to use the new FCM endpoint as shown below:class FCMSender extends Sender { public FCMSender(String key) { super(key); } @Override protected HttpURLConnection getConnection(String url) throws IOException { String fcmUrl = "https://fcm.googleapis.com/fcm/send"; return (HttpURLConnection) new URL(fcmUrl).openConnection(); } }
The
main()
method of my Java application looks like this:public static void main(String[] args) { // Obtain serverKey from Project Settings -> Cloud Messaging tab // for "My Notification Client" project in Firebase Console. String serverKey = <get_server_key_from_firebase_console>; Thread t = new Thread() { public void run(){ try { Sender sender = new FCMSender(serverKey); Message message = new Message.Builder() .collapseKey("message") .timeToLive(3) .delayWhileIdle(true) .addData("message", "Notification from Java application"); .build(); // Use the same token(or registration id) that was earlier // used to send the message to the client directly from // Firebase Console's Notification tab. Result result = sender.send(message, "APA91bFfIFjSCcSiJ111rbmkpnMkZY-Ej4RCpdBZFZN_mYgfHwFlx-M1UXS5FqDBcN8x1efrS2md8L9K_E9N21qB-PIHUqQwmF4p7Y3U-86nCGH7KNkZNjjz_P_qjcTR0TOrwXMh33vp", 1); System.out.println("Result: " + result.toString()); } catch (Exception e) { e.printStackTrace(); } }; t.start; try { t.join(); } catch (InterruptedException iex) { iex.printStackTrace(); } }
When I run the Java application, I get MismatchSenderId
error. I tried troubleshooting using curl
as shown below but got the same error:
$ skey=<obtained_from_project_settings_cloud_messaging_tab_in_firebase_console>
$ curl -X POST --header "Authorization: key=$skey" \
--Header "Content-Type: application/json" \
https://fcm.googleapis.com/fcm/send \
-d "{\"to\":\"APA91bFfIFjSCcSiJ111rbmkpnMkZY-Ej4RCpdBZFZN_mYgfHwFlx-M1UXS5FqDBcN8x1efrS2md8L9K_E9N21qB-PIHUqQwmF4p7Y3U-86nCGH7KNkZNjjz_P_qjcTR0TOrwXMh33vp\",\"data\":{\"message\":\"Yellow\"}}"
{"multicast_id":7391851081942579857,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"MismatchSenderId"}]}
Instead of using the Server Key
listed on Project Settings > Cloud Messaging
tab for My Notification Server
project in Firebase Console, I tried using the Project Number
but that caused InvalidRequestException: HTTP Status Code: 401
.
Firebase documentation of the error codes says this about MismatchSenderId
:
Mismatched Sender 200 +
error:MismatchSenderId
A registration token is tied to a certain group of senders. When a client app registers for FCM, it must specify which senders are allowed to send messages. You should use one of those sender IDs when sending messages to the client app. If you switch to a different sender, the existing registration tokens won't work.
I could not figure out where/how in Firebase Console one can configure the Android app(which was aded to the My Notification Client
project) to be able to receive messages.
Any help on this, would be appreciated!