Entérate de todos los anuncios de Firebase Summit y descubre cómo Firebase puede ayudarte a acelerar el desarrollo de las apps y a ejecutarlas con confianza. Más información

Migrar de HTTP heredado a HTTP v1

Las aplicaciones que usan la API HTTP heredada de FCM deben considerar migrar a la API HTTP v1 siguiendo las instrucciones de esta guía. La API HTTP v1 tiene estas ventajas sobre la API heredada:

  • Mejor seguridad a través de tokens de acceso La API HTTP v1 utiliza tokens de acceso de corta duración de acuerdo con el modelo de seguridad OAuth2. En el caso de que un token de acceso se haga público, solo se puede usar de forma malintencionada 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 se capturen.

  • Personalización más eficiente de los 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 plataforma que le permiten personalizar el mensaje entre plataformas. Esto le permite crear "anulaciones" que envían cargas ligeramente diferentes a diferentes plataformas de clientes en un solo mensaje.

  • Más extensible y preparado para el futuro para las nuevas versiones de la plataforma del cliente. 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 de JSON, FCM puede extender la API a nuevas versiones y nuevas 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 estos aspectos:

  • Está versionado, con /v1 en la ruta.
  • La ruta contiene el ID del proyecto de Firebase para su aplicación, en el formato /projects/myproject-ID/ . Este ID está disponible en la pestaña Configuración general del proyecto de Firebase console.
  • Especifica explícitamente especificar el método de 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.

Antes

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

Después

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

Actualizar autorización de solicitudes de envío

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 usa Admin SDK para enviar mensajes, la biblioteca maneja el token por usted. Si usa el 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

Según 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 la aplicación de Google (ADC)
  • Un archivo JSON de cuenta de servicio
  • Un token de acceso de 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 usa su cuenta de servicio predeterminada existente para obtener credenciales para autorizar solicitudes, y ADC habilita pruebas locales flexibles a través de la variable de entorno GOOGLE_APPLICATION_CREDENTIALS . Para la automatización más completa del flujo de autorización, use 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 de 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 dicho acceso al archivo, debe hacer referencia al archivo de la cuenta de servicio en su código, lo que debe hacerse con sumo cuidado debido al riesgo de exponer sus credenciales.

Proporcione credenciales usando ADC

Las credenciales predeterminadas de la aplicación de Google (ADC) 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 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()

Vamos

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 puede usar para llamar a las API del servidor de Firebase desde su servidor de aplicaciones o entorno de confianza. 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, abra Configuración > Cuentas de servicio .

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

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

Al autorizar 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 se recomienda encarecidamente.

Para establecer la variable de entorno:

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

Linux o mac OS

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 se ejecuta en entornos que no son de Google.

Use credenciales para acuñar tokens de acceso

Use sus credenciales de Firebase junto con la biblioteca de autenticación de Google de su idioma preferido para recuperar un token de acceso de 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 de la 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 = ServiceAccountCredentials.from_json_keyfile_name(
      'service-account.json', SCOPES)
  access_token_info = credentials.get_access_token()
  return access_token_info.access_token

Java

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

Una vez que caduca su token de acceso, se llama automáticamente al método de actualización de 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 el valor del encabezado de 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 " + getAccessToken());
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 aseguran que los mensajes se manejen correctamente cuando se reciben en diferentes plataformas de clientes; además, los cambios le brindan flexibilidad adicional para personalizar o "anular" los 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 la API para familiarizarse con HTTP v1.

Ejemplo: mensaje de notificación simple

Aquí hay una comparación de una carga útil de notificación muy simple, que contiene solo campos de title , body y data , que demuestra las diferencias fundamentales en 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: orientación a varias plataformas

Para habilitar la orientación multiplataforma, 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 las diferencias entre plataformas sean explícitas y visibles 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 selección de mensajes entre plataformas, la API HTTP v1 brinda 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: orientación 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 del token en lugar to la clave.

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 el blog de Firebase .