[英]Firebase Cloud Messaging notification from Java instead of Firebase Console
我是Firebase的新手,當我的Java應用程序嘗試使用客戶端的Firebase令牌發送通知/消息時,我遇到錯誤,例如錯誤的發件人ID和HTTP狀態401的身份驗證錯誤。 請注意,使用Firebase控制台,我可以將消息發送到客戶端。
對於客戶端應用程序,我執行了以下操作:
messaging
快速入門應用程序 - https://github.com/firebase/quickstart-android/tree/master/messaging - 已經設置了Firebase依賴等。 在Android Studio
加載了克隆的應用程序。 My Notification Client
的新項目,並使用com.google.firebase.quickstart.fcm
添加了一個應用,作為Android應用的包名稱。 google-services.json
文件,並將其復制到messaging/app/
文件夾,並與Android Studio
成績文件同步。 Android Studio
運行應用程序。 當應用程序加載到模擬器中時,單擊“ Log Token
按鈕以在Android Studio
的Android Monitor
選項卡中捕獲客戶端的Firebase標記。 My Notification Client
,單擊左窗格中的“ Notifications
鏈接,並通過粘貼上一步中捕獲的Firebase令牌向設備發送通知。 這很棒! 下一步是使用單獨的簡單Java應用程序(最終將成為通知服務器)將通知發送到客戶端而不是使用Firebase控制台。
為此,我按照此處列出的步驟進行了操作 - https://firebase.google.com/docs/server/setup#prerequisites 。 具體來說,這些是我執行的步驟:
My Notification Server
的新項目。 Settings > Permissions
,創建新服務帳戶並下載serviceAccountCredentials.json
文件。 <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>
然后,我擴展了com.google.android.gcm.sender.Sender
以創建FCMSender
並覆蓋受保護的方法getConnection(String url)
以使用新的FCM端點,如下所示:
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(); } }
我的Java應用程序的main()
方法如下所示:
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(); } }
當我運行Java應用程序時,我收到MismatchSenderId
錯誤。 我嘗試使用curl
故障排除,如下所示,但得到了同樣的錯誤:
$ 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"}]}
我沒有使用Firebase控制台中My Notification Server
項目的Project Settings > Cloud Messaging
選項卡上列出的Server Key
,而是嘗試使用Project Number
但導致InvalidRequestException: HTTP Status Code: 401
。
錯誤代碼的Firebase文檔說明了MismatchSenderId
:
不匹配的發件人200 +
error:MismatchSenderId
注冊令牌與某組發件人綁定。 當客戶端應用程序注冊FCM時,它必須指定允許哪些發件人發送消息。 在向客戶端應用程序發送消息時,您應該使用其中一個發件人ID。 如果您切換到其他發件人,現有的注冊令牌將無法使用。
我無法弄清楚Firebase控制台在哪里/如何配置Android應用程序(與My Notification Client
項目相關)以便能夠接收消息。
對此有任何幫助,將不勝感激!
我最近也開始使用Firebase,沒有谷歌雲消息傳遞方面的經驗。 AFAIK,目前還沒有適用於Firebase雲消息傳遞的服務器端SDK。
要將通知/消息從App Server發送到Mobile Client,您需要實現自己的HTTP和/或XMPP方法。 請參閱https://firebase.google.com/docs/cloud-messaging/
我的測試代碼,使用HTTP:
public CompletableFuture<String> fcmTest1() {
// https://firebase.google.com/docs/cloud-messaging/http-server-ref
String host = "fcm.googleapis.com";
String requestURI = "/fcm/send";
String CLIENT_TOKEN = "ASK_YOUR_MOBILE_CLIENT_DEV"; // https://developers.google.com/instance-id/
CompletableFuture<String> fut = new CompletableFuture<>();
JsonObject body = new JsonObject();
// JsonArray registration_ids = new JsonArray();
// body.put("registration_ids", registration_ids);
body.put("to", CLIENT_TOKEN);
body.put("priority", "high");
// body.put("dry_run", true);
JsonObject notification = new JsonObject();
notification.put("body", "body string here");
notification.put("title", "title string here");
// notification.put("icon", "myicon");
JsonObject data = new JsonObject();
data.put("key1", "value1");
data.put("key2", "value2");
body.put("notification", notification);
body.put("data", data);
HttpClientRequest hcr = httpsClient.post(443, host, requestURI).handler(response -> {
response.bodyHandler(buffer -> {
logger.debug("FcmTest1 rcvd: {}, {}", response.statusCode(), buffer.toString());
if (response.statusCode() == 200) {
fut.complete(buffer.toString());
} else {
fut.completeExceptionally(new RuntimeException(buffer.toString()));
}
});
});
hcr.putHeader("Authorization", "key=" + Utils.FIREBASE_SERVER_KEY)
.putHeader("content-type", "application/json").end(body.encode());
return fut;
}
注意:http客戶端和json是由vertx( http://vertx.io/ )提供的,但希望代碼能夠清楚地顯示出足夠清晰的內容,以便您可以使用任何您想要的內容。
我遇到了同樣的問題。 問題在於:
String serverKey = <get_server_key_from_firebase_console>;
此值應來自Android應用程序項目; 在這種情況下,它將是“我的通知客戶端”而不是“我的通知服務器”。
我寫了一個FCMHelper類,工作正常,使用簡單。
我需要從我的java EE應用程序發送FCM通知,我發現這非常有用。 可能會節省一些時間。
... github repo是Firebase雲消息傳遞(FCM)API的庫接口(NB //我不是作者)。 所以我按照自述文件中的說明操作:將jar文件添加為我的項目的依賴項,並且可以使用各自的參數調用庫方法。
例如Pushraven.setKey(my_key);
設置您的服務器密鑰和
Notification raven = new Notification();
raven.title("MyTitle")
.text("Hello World!")
.color("#ff0000")
.to(client_key);
建立通知。 回購的說明非常明確且有用。
上:
// Obtain serverKey from Project Settings -> Cloud Messaging tab // for "My Notification Server" project in Firebase Console. String serverKey = <get_server_key_from_firebase_console>;
您必須獲取Android應用程序的密鑰。
謝謝你,我正在努力構建一個服務來發送/接收應用程序的通知。 看到你的問題,試圖把它弄好,然后用來建造我的。 希望對你有幫助 :)
我有同樣的問題,甚至用你的代碼作為測試來檢查我的是否有問題。 事實證明,我們的兩個代碼都是正確的。 Firebase文檔中描述的問題非常明顯:
“不匹配的發件人200 +錯誤:MismatchSenderId注冊令牌綁定到某組發件人。當客戶端應用程序注冊FCM時,它必須指定允許哪些發件人發送郵件。您應該在發送郵件時使用其中一個發件人ID到客戶端應用程序。如果您切換到其他發件人,現有的注冊令牌將無效。“
問題是,這不是那么清楚(至少不適合我)。 這就是您需要的:在您的Android應用程序中,您需要接收設備的Firebase密鑰。 它與您以前用於Google Cloud Message的方式不同,因此存在問題。
只需在Android項目上創建此類:
public class NotificacaoRegistro擴展FirebaseInstanceIdService {static private String TAG =“NOTIFICACAOREGISTRO”;
public NotificacaoRegistro(){
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
}
@Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
// TODO: Implement this method to send any registration to your app's servers.
}
}
不要忘記在AndroidManifest上進行必要的更改
<service
android:name=".notificacoes.NotificacaoRegistro">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
如果您只需要代碼(例如,用於調試),您可以在OnCreate方法中調用MainActivity
String refreshedToken = FirebaseInstanceId.getInstance()。getToken();
但是如果你妥善處理它,那就更好了。
這樣你就可以獲得該設備的正確密鑰。 然后在您的Java應用程序代碼上
Result result = sender.send(message,
<PUT THE VALUE OF THE REFRESHED TOKEN HERE>,
1);
而且你們都准備好了:)
希望這會有所幫助,並對長時間的延遲感到抱歉:)
干杯
Spring框架
與其他項目相比,只有3個簡單的類具有最小的依賴性。
https://github.com/AndreiD/testingpushnotifications
請記住替換SERVER_API_KEY和Client_Token。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.