Firebase Cloud Messaging notification from Java instead of Firebase Console
<p>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.</p>

<p>For the client app, I did the following:</p>

<ol>
<li>Cloned Firebase <code>messaging</code> quickstart app from here -- <a href="https://github.com/firebase/quickstart-android/tree/master/messaging" rel="noreferrer">https://github.com/firebase/quickstart-android/tree/master/messaging</a> -- which is already setup with Firebase dependencies and such. Loaded the cloned app in <code>Android Studio</code>.</li>
<li>Using Firebase Console, created a new project called <code>My Notification Client</code> and added an app using <code>com.google.firebase.quickstart.fcm</code> as the package name of the Android app.</li>
<li>Downloaded <code>google-services.json</code> file for the Android app added to the newly created project and copied it to the <code>messaging/app/</code> folder and sync'd with Grade files from within <code>Android Studio</code>.</li>
<li>Created an emulator and ran the app from within <code>Android Studio</code>. When the app got loaded in the emulator, clicked the <code>Log Token</code> button to capture the client's Firebase token in the <code>Android Monitor</code> tab in <code>Android Studio</code>.</li>
<li>Using Firebase Console, selected the newly created project <code>My Notification Client</code>, clicked the <code>Notifications</code> link from the left pane, and sent a notification to the device by pasting the Firebase token captured in the previous step.</li>
</ol>

<p>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.</p>

<p>To accomplish this, I followed the steps outlined here -- <a href="https://firebase.google.com/docs/server/setup#prerequisites" rel="noreferrer">https://firebase.google.com/docs/server/setup#prerequisites</a>. Specifically, these are the steps that I performed: </p>

<ol>
<li>Created a new project called <code>My Notification Server</code> in Firebase Console.</li>
<li>Using <code>Settings &gt; Permissions</code> in Firebase Console, created a new service account and downloaded the <code>serviceAccountCredentials.json</code> file.</li>
<li>Created a new maven project in Eclipse and added the following dependencies in pom.xml:</li>
</ol>

<pre class="lang-xml prettyprint-override"><code>    &lt;dependency&gt;
      &lt;groupId&gt;com.google.gcm&lt;/groupId&gt;
      &lt;artifactId&gt;gcm-server&lt;/artifactId&gt;
      &lt;version&gt;1.0.0&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;com.googlecode.json-simple&lt;/groupId&gt;
      &lt;artifactId&gt;json-simple&lt;/artifactId&gt;
      &lt;version&gt;1.1.1&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;com.google.firebase&lt;/groupId&gt;
      &lt;artifactId&gt;firebase-server-sdk&lt;/artifactId&gt;
      &lt;version&gt;3.0.0&lt;/version&gt;
    &lt;/dependency&gt;
</code></pre>

<ol>
<li><p>Then, I extended <code>com.google.android.gcm.sender.Sender</code> to create <code>FCMSender</code> and override protected method <code>getConnection(String url)</code> to use the new FCM endpoint as shown below:</p>

<pre><code>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();
    }
}
</code></pre></li>
<li><p>The <code>main()</code> method of my Java application looks like this:</p>

<pre><code>public static void main(String[] args) {
    // Obtain serverKey from Project Settings -&gt; Cloud Messaging tab
    // for "My Notification Client" project in Firebase Console.
    String serverKey = &lt;get_server_key_from_firebase_console&gt;;
    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();
        }
    }
</code></pre></li>
</ol>

<p>When I run the Java application, I get <code>MismatchSenderId</code> error. I tried troubleshooting using <code>curl</code> as shown below but got the same error:</p>

<pre><code>$ skey=&lt;obtained_from_project_settings_cloud_messaging_tab_in_firebase_console&gt;
$ 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"}]}
</code></pre>

<p>Instead of using the <code>Server Key</code> listed on <code>Project Settings &gt; Cloud Messaging</code> tab for <code>My Notification Server</code> project in Firebase Console, I tried using the <code>Project Number</code> but that caused <code>InvalidRequestException: HTTP Status Code: 401</code>.</p>

<p>Firebase documentation of the error codes says this about <code>MismatchSenderId</code>:</p>

<blockquote>
  <p>Mismatched Sender 200 + <code>error:MismatchSenderId</code><br>
  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.</p>
</blockquote>

<p>I could not figure out where/how in Firebase Console one can configure the Android app(which was aded to the <code>My Notification Client</code> project) to be able to receive messages.</p>

<p>Any help on this, would be appreciated!</p>