19

I am struggling with the new FCM... I used FCM before, now I am trying FCM...

I am trying to send push notification for my app server to android device.

I wanna use the standard Java package, try not to use others such as Vert.x, apache's httpClient etc...

here is my code:

public void sendNotification(String messageBody)
{
    try
    {
        URL url = new URL("https://fcm.googleapis.com/fcm/send");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json");

        String apiKey = "AI...wE";

        String credentials = "key=" + apiKey;
        //String basicAuth = "Basic " + Base64.getEncoder().encodeToString(credentials.getBytes());

        String basicAuth = "Basic " + new String(Base64.encodeBase64(credentials.getBytes()));

        conn.setRequestProperty ("Authorization", basicAuth);

        String notfnStr = "{\"body\": \"this is my body\", \"title\": \"this is my title\"}";
        String dataStr = "{\"key1\": \"value1\", \"key2\": \"value2\"}";

        String bodyStr = "{\"priority\": \"high\", \"to\": \"dFC8GW0N1Q8:APA91bHePPmC7QVV16LGnR6rqxwreHSv1GgawijZ_dZL9T70ZkiXIV8TW_ymAWkvFfXRiWJmtR_UGBXBv2iV2UhS8M-Tndw8sf8ZW6zIqfaiiVJao3G5HFbhqgA18ukNNtW_J7JaWkz8\", " +
                "\"notification\": " + notfnStr + ", \"data\": " + dataStr + "}";

        System.out.println("### input: " + bodyStr);

        OutputStream os = conn.getOutputStream();
        os.write(bodyStr.getBytes());
        os.flush();

        if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED) {
            throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
        }

        BufferedReader br = new BufferedReader(new InputStreamReader(
                (conn.getInputStream())));

        String output;
        System.out.println("Output from Server .... \n");
        while ((output = br.readLine()) != null) {
            System.out.println(output);
        }

        conn.disconnect();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

the response code i got is 401, which means unauthorized... i guess the format of credential is wrong...

The json string is in valid json format, so i don't bother to use JSONObject.

For the string credentials, i have tried "key:" + apiKey; but still got the same result.

The apiKey String is copied from the google-services.json I downloaded from Firebase console in google.

google didn't give a good example... just gave me this: https://firebase.google.com/docs/cloud-messaging/downstream

If any one knows how to do it, please reply. Thanks!!

4 Answers 4

22

FULL EXAMPLE USE THIS FOR SEND NOTIFICATION USING FCM IN JAVA

public class FCMNotification {

    // Method to send Notifications from server to client end.
    public final static String AUTH_KEY_FCM = "API_KEY_HERE";
    public final static String API_URL_FCM = "https://fcm.googleapis.com/fcm/send";

    public static void pushFCMNotification(String DeviceIdKey) throws Exception {

        String authKey = AUTH_KEY_FCM; // You FCM AUTH key
        String FMCurl = API_URL_FCM;

        URL url = new URL(FMCurl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        conn.setUseCaches(false);
        conn.setDoInput(true);
        conn.setDoOutput(true);

        conn.setRequestMethod("POST");
        conn.setRequestProperty("Authorization", "key=" + authKey);
        conn.setRequestProperty("Content-Type", "application/json");

        JSONObject data = new JSONObject();
        data.put("to", DeviceIdKey.trim());
        JSONObject info = new JSONObject();
        info.put("title", "FCM Notificatoin Title"); // Notification title
        info.put("text", "Hello First Test notification"); // Notification body
        data.put("notification", info);

        OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
        wr.write(data.toString());
        wr.flush();
        wr.close();

        int responseCode = conn.getResponseCode();
        System.out.println("Response Code : " + responseCode);

        BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

    }

    @SuppressWarnings("static-access")
    public static void main(String[] args) throws Exception {
        FCMNotification.pushFCMNotification("USER_DEVICE_TOKEN");
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

This is amazing.
find that.. change to for registration_ids add JSONArray
not working using Java 8 and Gson for JSON, still getting 401
since the pushFCMNotification method static there is no need to create an instance from FCMNotification i have edited this
@BasilBattikhi Can you give me example/reference of it.
2

You mentioned that you got he key from the google-services.json file. That would be your Android API key, not the server key required to send FCM messages. In the Firebase console go to Settings > Cloud Messaging > Server key for the API key to be used for sending FCM messages.

3 Comments

Hi. Just a quick question sir Thompson. @fkie4 also mentioned that he downloaded the google-services.json file from the Firebase Console. Doesn't the Firebase Console automatically provide the corresponding Server Key in the google-services.json?
Ha! it is working now. Thanks! I was using a wrong API key... also, no base64 encoding is used. i use conn.setRequestProperty ("Authorization", "key=" + apiKey); Thanks @frank !!
Np. @intj No the server key should never really be included with or used by the client application.
1

This is a function using to send notification from java to the app android. this code use JSONObject you must add this jar into project buildpath.

note:I use fcm

import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONObject;

public class FcmNotif {
public final static String AUTH_KEY_FCM ="AIzB***********RFA";

public final static String API_URL_FCM ="https://fcm.googleapis.com/fcm/send";

         // userDeviceIdKey is the device id you will query from your database

    public void pushFCMNotification(String userDeviceIdKey, String title, String message) throws Exception{

    String authKey = AUTH_KEY_FCM;   // You FCM AUTH key
    String FMCurl = API_URL_FCM;     

    URL url = new URL(FMCurl);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();

    conn.setUseCaches(false);
    conn.setDoInput(true);
    conn.setDoOutput(true);

    conn.setRequestMethod("POST");
    conn.setRequestProperty("Authorization","key="+authKey);
    conn.setRequestProperty("Content-Type","application/json");

    JSONObject json = new JSONObject();
    json.put("to",userDeviceIdKey.trim());
    JSONObject info = new JSONObject();
    info.put("title", title); // Notification title
    info.put("body", message); // Notification body
    info.put("image", "https://lh6.googleusercontent.com/-sYITU_cFMVg/AAAAAAAAAAI/AAAAAAAAABM/JmQNdKRPSBg/photo.jpg");
    info.put("type", "message");
    json.put("data", info);
    System.out.println(json.toString());

    OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
    wr.write(json.toString());
    wr.flush();
    conn.getInputStream();
    }
    }

good luck

2 Comments

Hi, I'm receiving a mismatchId error. Where is userDeviceIdKey come from? I'm using the one received from the VAPID REQUEST, which comes attached with "endpoint":"fcm.googleapis.com/fcm/send/<THIS IS WHAT I PASS>", but it doesn't work. Can you help us? Tnx!
You get the userDeviceIDKey(Token) when you install your app in mobile phone then you can stock it in your database and when you want to send notification select it and pass it in this function. it works fine.
0

As far as I know there is no need to base64 encode the credentials:

String apiKey = "AI...wE";
String credentials = "key=" + apiKey;
conn.setRequestProperty ("Authorization", credentials);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.