Notificación de Firebase Cloud Messaging desde Java en lugar de Firebase Console
Soy nuevo en Firebase y me encuentro con errores como una identificación de remitente incompatible y un error de autenticación con el estado HTTP 401 cuando mi aplicación Java intenta enviar una notificación / mensaje utilizando el token Firebase del cliente. Tenga en cuenta que con Firebase Console, puedo enviar el mensaje al cliente.
Para la aplicación cliente, hice lo siguiente:
Base de fuego clonadamessaging
aplicación de inicio rápido desde aquí:https://github.com/firebase/quickstart-android/tree/master/messaging - que ya está configurado con dependencias de Firebase y demás. Cargué la aplicación clonada enAndroid Studio
.Usando Firebase Console, creó un nuevo proyecto llamadoMy Notification Client
y agregó una aplicación usandocom.google.firebase.quickstart.fcm
como el nombre del paquete de la aplicación de Android.Descargadogoogle-services.json
archivo para la aplicación de Android agregado al proyecto recién creado y copiado almessaging/app/
carpeta y sincronizado con archivos de calificación desde dentroAndroid Studio
.Creé un emulador y ejecuté la aplicación desde dentroAndroid Studio
. Cuando la aplicación se cargó en el emulador, hizo clic enLog Token
botón para capturar el token Firebase del cliente en elAndroid Monitor
pestaña enAndroid Studio
.Usando Firebase Console, seleccioné el proyecto recién creadoMy Notification Client
, hizo clic enNotifications
enlace desde el panel izquierdo y envió una notificación al dispositivo pegando el token de Firebase capturado en el paso anterior.Esto funcionó muy bien! El siguiente paso fue usar una aplicación Java simple separada (que eventualmente se convertiría en un servidor de notificaciones) para enviar la notificación al cliente en lugar de usar Firebase Console.
Para lograr esto, seguí los pasos descritos aquí:https://firebase.google.com/docs/server/setup#prerequisites. Específicamente, estos son los pasos que realicé:
Creó un nuevo proyecto llamadoMy Notification Server
en Firebase Console.UtilizandoSettings > Permissions
en Firebase Console, creó una nueva cuenta de servicio y descargó elserviceAccountCredentials.json
archivo.Creó un nuevo proyecto maven en Eclipse y agregó las siguientes dependencias en 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>
Entonces, extendícom.google.android.gcm.sender.Sender
crearFCMSender
y anular el método protegidogetConnection(String url)
para usar el nuevo punto final FCM como se muestra a continuación:
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();
}
}
losmain()
El método de mi aplicación Java se ve así:
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();
}
}
Cuando ejecuto la aplicación Java, obtengoMismatchSenderId
error. Intenté solucionar problemas usandocurl
como se muestra a continuación, pero obtuvo el mismo 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"}]}
En lugar de usar elServer Key
listado enProject Settings > Cloud Messaging
pestaña paraMy Notification Server
proyecto en Firebase Console, intenté usar elProject Number
pero eso causóInvalidRequestException: HTTP Status Code: 401
.
La documentación de Firebase de los códigos de error dice esto sobreMismatchSenderId
:
Remitente incompatible 200+error:MismatchSenderId
Un token de registro está vinculado a un determinado grupo de remitentes. Cuando una aplicación cliente se registra para FCM, debe especificar qué remitentes pueden enviar mensajes. Debe usar una de esas ID de remitente al enviar mensajes a la aplicación cliente. Si cambia a un remitente diferente, los tokens de registro existentes no funcionarán.
No pude averiguar dónde / cómo en Firebase Console se puede configurar la aplicación de Android (que se agregó alMy Notification Client
proyecto) para poder recibir mensajes.
¡Cualquier ayuda en esto sería apreciada!