Migrar desde las API de FCM heredadas a HTTP v1

Las aplicaciones que utilizan las API heredadas de FCM en desuso para HTTP y XMPP deben migrar a la API HTTP v1 lo antes posible. El envío de mensajes (incluidos los mensajes ascendentes) con esas API quedó obsoleto el 20 de junio de 2023 y se eliminará en junio de 2024 .

Además del soporte continuo y las nuevas funciones, la API HTTP v1 tiene estas ventajas sobre las API heredadas:

  • Mejor seguridad mediante tokens de acceso La API HTTP v1 utiliza tokens de acceso de corta duración según el modelo de seguridad OAuth2. En caso de que un token de acceso se vuelva público, solo se puede utilizar de forma maliciosa durante aproximadamente una hora antes de que caduque. Los tokens de actualización no se transmiten con tanta frecuencia como las claves de seguridad utilizadas en la API heredada, por lo que es mucho menos probable que sean capturados.

  • Personalización más eficiente de mensajes entre plataformas Para el cuerpo del mensaje, la API HTTP v1 tiene claves comunes que van a todas las instancias de destino, además de claves específicas de la plataforma que le permiten personalizar el mensaje entre plataformas. Esto le permite crear "anulaciones" que envían cargas útiles ligeramente diferentes a diferentes plataformas de clientes en un solo mensaje.

  • Más ampliable y preparada para el futuro para nuevas versiones de plataformas de clientes. La API HTTP v1 es totalmente compatible con las opciones de mensajería disponibles en las plataformas Apple, Android y Web. Dado que cada plataforma tiene su propio bloque definido en la carga útil JSON, FCM puede extender la API a nuevas versiones y plataformas según sea necesario.

Actualizar el punto final del servidor

La URL del punto final para la API HTTP v1 difiere del punto final heredado en los siguientes aspectos:

  • Está versionado, con /v1 en la ruta.
  • La ruta contiene el ID del proyecto de Firebase para tu aplicación, en el formato /projects/myproject-ID/ . Esta ID está disponible en la pestaña Configuración general del proyecto de Firebase console.
  • Especifica explícitamente el método send como :send .

Para actualizar el punto final del servidor para HTTP v1, agregue estos elementos al punto final en el encabezado de sus solicitudes de envío.

Solicitudes HTTP antes

POST https://fcm.googleapis.com/fcm/send

Solicitudes XMPP antes

Los mensajes XMPP heredados se envían a través de una conexión al siguiente punto final:

fcm-xmpp.googleapis.com:5235

Después

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send

Actualizar autorización de envío de solicitudes

En lugar de la cadena de clave del servidor utilizada en las solicitudes heredadas, las solicitudes de envío HTTP v1 requieren un token de acceso OAuth 2.0. Si está utilizando el SDK de administración para enviar mensajes, la biblioteca maneja el token por usted. Si utiliza un protocolo sin formato, obtenga el token como se describe en esta sección y agréguelo al encabezado como Authorization: Bearer <valid Oauth 2.0 token> .

Antes

Authorization: key=AIzaSyZ-1u...0GBYzPu7Udno5aA

Después

Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA

Dependiendo de los detalles de su entorno de servidor, use una combinación de estas estrategias para autorizar solicitudes de servidor a los servicios de Firebase:

  • Credenciales predeterminadas de aplicaciones de Google (ADC)
  • Un archivo JSON de cuenta de servicio
  • Un token de acceso OAuth 2.0 de corta duración derivado de una cuenta de servicio

Si su aplicación se ejecuta en Compute Engine, Google Kubernetes Engine, App Engine o Cloud Functions (incluidas Cloud Functions para Firebase), use las credenciales predeterminadas de la aplicación (ADC). ADC utiliza su cuenta de servicio predeterminada existente para obtener credenciales para autorizar solicitudes, y ADC permite pruebas locales flexibles a través de la variable de entorno GOOGLE_APPLICATION_CREDENTIALS . Para lograr la máxima automatización del flujo de autorización, utilice ADC junto con las bibliotecas del servidor Admin SDK.

Si su aplicación se ejecuta en un entorno de servidor que no es de Google , deberá descargar un archivo JSON de cuenta de servicio desde su proyecto de Firebase. Siempre que tenga acceso a un sistema de archivos que contenga el archivo de clave privada, puede usar la variable de entorno GOOGLE_APPLICATION_CREDENTIALS para autorizar solicitudes con estas credenciales obtenidas manualmente. Si no tiene acceso a dicho archivo, debe hacer referencia al archivo de la cuenta de servicio en su código, lo cual debe hacerse con extremo cuidado debido al riesgo de exponer sus credenciales.

Proporcionar credenciales mediante ADC

Las Credenciales predeterminadas de la aplicación (ADC) de Google verifican sus credenciales en el siguiente orden:

  1. ADC comprueba si la variable de entorno GOOGLE_APPLICATION_CREDENTIALS está configurada. Si la variable está configurada, ADC usa el archivo de cuenta de servicio al que apunta la variable.

  2. Si la variable de entorno no está configurada, ADC usa la cuenta de servicio predeterminada que Compute Engine, Google Kubernetes Engine, App Engine y Cloud Functions proporcionan para las aplicaciones que se ejecutan en esos servicios.

  3. Si ADC no puede usar ninguna de las credenciales anteriores, el sistema genera un error.

El siguiente ejemplo de código del SDK de administración ilustra esta estrategia. El ejemplo no especifica explícitamente las credenciales de la aplicación. Sin embargo, ADC puede encontrar implícitamente las credenciales siempre que la variable de entorno esté configurada o siempre que la aplicación se ejecute en Compute Engine, Google Kubernetes Engine, App Engine o Cloud Functions.

Nodo.js

admin.initializeApp({
  credential: admin.credential.applicationDefault(),
});

Java

FirebaseOptions options = FirebaseOptions.builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    .setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
    .build();

FirebaseApp.initializeApp(options);

Pitón

default_app = firebase_admin.initialize_app()

Ir

app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

C#

FirebaseApp.Create(new AppOptions()
{
    Credential = GoogleCredential.GetApplicationDefault(),
});

Proporcionar credenciales manualmente

Los proyectos de Firebase admiten cuentas de servicio de Google, que puedes usar para llamar a las API del servidor de Firebase desde tu servidor de aplicaciones o entorno confiable. Si está desarrollando código localmente o implementando su aplicación localmente, puede usar las credenciales obtenidas a través de esta cuenta de servicio para autorizar las solicitudes del servidor.

Para autenticar una cuenta de servicio y autorizarla a acceder a los servicios de Firebase, debe generar un archivo de clave privada en formato JSON.

Para generar un archivo de clave privada para su cuenta de servicio:

  1. En Firebase console, abre Configuración > Cuentas de servicio .

  2. Haga clic en Generar nueva clave privada y luego confirme haciendo clic en Generar clave .

  3. Almacene de forma segura el archivo JSON que contiene la clave.

Al realizar la autorización a través de una cuenta de servicio, tiene dos opciones para proporcionar las credenciales a su aplicación. Puede configurar la variable de entorno GOOGLE_APPLICATION_CREDENTIALS o puede pasar explícitamente la ruta a la clave de la cuenta de servicio en el código. La primera opción es más segura y muy recomendable.

Para configurar la variable de entorno:

Establezca la variable de entorno GOOGLE_APPLICATION_CREDENTIALS en la ruta del archivo JSON que contiene su clave de cuenta de servicio. Esta variable solo se aplica a su sesión actual de Shell, por lo que si abre una nueva sesión, configure la variable nuevamente.

Linux o macOS

export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"

ventanas

Con PowerShell:

$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"

Una vez que haya completado los pasos anteriores, las Credenciales predeterminadas de la aplicación (ADC) pueden determinar implícitamente sus credenciales, lo que le permite usar las credenciales de la cuenta de servicio cuando realiza pruebas o ejecuta en entornos que no son de Google.

Utilice credenciales para acuñar tokens de acceso

Utilice sus credenciales de Firebase junto con la biblioteca de autenticación de Google para su idioma preferido para recuperar un token de acceso OAuth 2.0 de corta duración:

nodo.js

 function getAccessToken() {
  return new Promise(function(resolve, reject) {
    const key = require('../placeholders/service-account.json');
    const jwtClient = new google.auth.JWT(
      key.client_email,
      null,
      key.private_key,
      SCOPES,
      null
    );
    jwtClient.authorize(function(err, tokens) {
      if (err) {
        reject(err);
        return;
      }
      resolve(tokens.access_token);
    });
  });
}

En este ejemplo, la biblioteca cliente API de Google autentica la solicitud con un token web JSON o JWT. Para obtener más información, consulte Tokens web JSON .

Pitón

def _get_access_token():
  """Retrieve a valid access token that can be used to authorize requests.

  :return: Access token.
  """
  credentials = service_account.Credentials.from_service_account_file(
    'service-account.json', scopes=SCOPES)
  request = google.auth.transport.requests.Request()
  credentials.refresh(request)
  return credentials.token

Java

private static String getAccessToken() throws IOException {
  GoogleCredentials googleCredentials = GoogleCredentials
          .fromStream(new FileInputStream("service-account.json"))
          .createScoped(Arrays.asList(SCOPES));
  googleCredentials.refresh();
  return googleCredentials.getAccessToken().getTokenValue();
}

Una vez que caduque su token de acceso, se llama automáticamente al método de actualización del token para recuperar un token de acceso actualizado.

Para autorizar el acceso a FCM, solicite el alcance https://www.googleapis.com/auth/firebase.messaging .

Para agregar el token de acceso a un encabezado de solicitud HTTP:

Agregue el token como valor del encabezado Authorization en el formato Authorization: Bearer <access_token> :

nodo.js

headers: {
  'Authorization': 'Bearer ' + accessToken
}

Pitón

headers = {
  'Authorization': 'Bearer ' + _get_access_token(),
  'Content-Type': 'application/json; UTF-8',
}

Java

URL url = new URL(BASE_URL + FCM_SEND_ENDPOINT);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Authorization", "Bearer " + getServiceAccountAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;

Actualizar la carga útil de las solicitudes de envío

FCM HTTP v1 introduce un cambio significativo en la estructuración de la carga útil del mensaje JSON. Principalmente, estos cambios garantizan que los mensajes se manejen correctamente cuando se reciban en diferentes plataformas de cliente; Además, los cambios le brindan flexibilidad adicional para personalizar o "anular" campos de mensajes por plataforma.

Además de inspeccionar los ejemplos de esta sección, consulte Personalización de un mensaje entre plataformas y revise la referencia de API para familiarizarse con HTTP v1.

Ejemplo: mensaje de notificación simple

A continuación se muestra una comparación de una carga útil de notificación muy simple (que contiene únicamente campos title , body y data que demuestra las diferencias fundamentales entre las cargas útiles heredadas y HTTP v1.

Antes

{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available."
  },
  "data": {
    "story_id": "story_12345"
  }
}

Después

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    }
  }
}

Ejemplo: apuntar a múltiples plataformas

Para habilitar la orientación a múltiples plataformas, la API heredada realizó anulaciones en el backend. Por el contrario, HTTP v1 proporciona bloques de claves específicos de la plataforma que hacen que cualquier diferencia entre plataformas sea explícita y visible para el desarrollador. Esto le permite apuntar a múltiples plataformas siempre con una sola solicitud, como se demuestra en el siguiente ejemplo.

Antes

// Android
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "TOP_STORY_ACTIVITY"
  },
  "data": {
    "story_id": "story_12345"
  }
}
// Apple
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "HANDLE_BREAKING_NEWS"
  },
  "data": {
    "story_id": "story_12345"
  }
}

Después

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    },
    "android": {
      "notification": {
        "click_action": "TOP_STORY_ACTIVITY"
      }
    },
    "apns": {
      "payload": {
        "aps": {
          "category" : "NEW_MESSAGE_CATEGORY"
        }
      }
    }
  }
}

Ejemplo: personalización con anulaciones de plataforma

Además de simplificar la segmentación de mensajes entre plataformas, la API HTTP v1 proporciona flexibilidad para personalizar los mensajes por plataforma.

Antes

// Android
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "Check out the Top Story.",
    "click_action": "TOP_STORY_ACTIVITY"
  },
  "data": {
    "story_id": "story_12345"
  }
}
// Apple
{
  "to": "/topics/news",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available.",
    "click_action": "HANDLE_BREAKING_NEWS"
  },
  "data": {
    "story_id": "story_12345"
  }
}

Después

{
  "message": {
    "topic": "news",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    },
    "android": {
      "notification": {
        "click_action": "TOP_STORY_ACTIVITY",
        "body": "Check out the Top Story"
      }
    },
    "apns": {
      "payload": {
        "aps": {
          "category" : "NEW_MESSAGE_CATEGORY"
        }
      }
    }
  }
}

Ejemplo: apuntar a dispositivos específicos

Para apuntar a dispositivos específicos con la API HTTP v1, proporcione el token de registro actual del dispositivo en la clave token en lugar de la clave to .

Antes

  { "notification": {
      "body": "This is an FCM notification message!",
      "time": "FCM Message"
    },
    "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
  }

Después

{
   "message":{
      "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
      "notification":{
        "body":"This is an FCM notification message!",
        "title":"FCM Message"
      }
   }
}

Para obtener más ejemplos e información sobre la API HTTP v1 de FCM, consulte lo siguiente: