1. Introducción
Última actualización: 4 de abril de 2022
En este codelab, se explica el proceso de desarrollo de una app multiplataforma con Firebase Cloud Messaging (FCM) con Flutter. Escribirás una parte de la implementación de la app y, luego, la compilarás y ejecutarás sin problemas en tres plataformas: Android, iOS y la Web. También aprenderás a integrar FCM en Flutter y a escribir código para recibir y enviar mensajes. Por último, en el codelab se presenta la función de bloques específicos de la plataforma de la API de FCM HTTP v1, que te permite enviar un mensaje con comportamientos diferentes en distintas plataformas.
Requisitos previos
Conocimientos básicos sobre Flutter
Qué aprenderás
- Cómo configurar y crear una app de Flutter
- Cómo agregar dependencias de FCM
- Cómo enviar mensajes únicos de FCM a tu app
- Cómo enviar mensajes de FCM por temas a tu app
Requisitos
- La versión estable más reciente de Android Studio configurada con los complementos de Dart y Flutter
Puedes ejecutar el codelab con cualquiera de los siguientes dispositivos:
- Un dispositivo Android físico conectado a tu computadora
- Un emulador de Android (consulta Cómo ejecutar apps en Android Emulator)
- El navegador que prefieras, como Chrome
De manera opcional, para ejecutar el codelab con la plataforma iOS, necesitas un dispositivo iOS, una cuenta de desarrollador de Apple y un dispositivo macOS con Xcode instalado.
2. Configuración de Flutter
Si ya tienes configurado un entorno de desarrollo de Flutter, omite esta sección.
Para configurar un entorno de desarrollo de Flutter, sigue estos pasos:
- Descarga e instala Flutter para tu sistema operativo: Instalar | Flutter
- Asegúrate de agregar la herramienta Flutter a tu ruta.
- Configura tu editor para Flutter como se muestra en Configura un editor | Flutter Asegúrate de instalar los complementos de Flutter y Dart para tu editor. Durante el resto del codelab, utilizarás Android Studio.
- Desde la línea de comandos, ejecuta
flutter doctor
, que analiza tu configuración y enumera las dependencias faltantes que deben corregirse. Sigue las instrucciones para corregir cualquier dependencia importante que falte. Ten en cuenta que es posible que algunas dependencias no sean necesarias. Por ejemplo, si no vas a desarrollar para iOS, una dependencia de CocoaPods faltante no será un problema de bloqueo. - Ejecuta este comando para crear tu app de Flutter en el directorio
fcmflutter
flutter create --org com.flutter.fcm --project-name fcmflutter fcmflutter
y, luego, cambia los directorios afcmflutter
.
- En Android Studio, ve a File -> Open, busca la ruta de acceso de tu app de Flutter y haz clic en Open para abrir el proyecto en Android Studio. El código de la app se encuentra en el archivo
lib/main.dart
.
En la barra de herramientas de Android Studio, haz clic en la flecha hacia abajo para seleccionar un dispositivo Android. Si el selector de destino está vacío, instala dispositivos virtuales Android, el navegador Chrome o el simulador de iOS si prefieres iniciar la app desde un navegador web o un dispositivo iOS. Es posible que debas iniciar el dispositivo manualmente y actualizar la lista para encontrar el dispositivo de destino.
Haz clic en Run para iniciar la app.
¡Felicitaciones! Creaste correctamente una app de Flutter.
3. Configuración de Firebase y FlutterFire
Para desarrollar una app que se integre con Firebase Cloud Messaging mediante Flutter, necesitarás lo siguiente:
- Un proyecto de Firebase
- Una Firebase CLI que funcione
- Una instalación de FlutterFire
- Una app configurada y generada con
flutterfire configure
Crea tu proyecto de Firebase
Si ya tienes un proyecto de Firebase, puedes omitir este paso.
- Si tienes una Cuenta de Google, abre Firebase, accede con ella y haz clic en Ir a la consola.
- En Firebase console, haz clic en Agregar proyecto. Sigue las instrucciones para crear un proyecto. No marques la opción Habilitar Google Analytics para este proyecto porque no lo usarás en este proyecto.
- Después de crear el proyecto, navega a su Configuración del proyecto. Para ello, haz clic en el ícono de ajustes junto a Descripción general del proyecto.
El ID del proyecto se usa para identificar el proyecto de forma única y puede ser diferente del Nombre del proyecto. El ID del proyecto se usará para configurar FlutterFire más adelante.
¡Felicitaciones! Creaste correctamente un proyecto de Firebase.
Configura Firebase CLI
Si configuraste Firebase CLI, puedes omitir este paso.
Ve a la Referencia de Firebase CLI para descargar y, luego, instalar Firebase CLI. Usa el siguiente comando para acceder a Firebase con tu Cuenta de Google:
firebase login
Configura FlutterFire
- Instala el complemento de FlutterFire con el comando:
flutter pub add firebase_core
. - Instala el complemento de FCM:
flutter pub add firebase_messaging
- Configura la CLI de FlutterFire:
dart pub global activate flutterfire_cli
- Configura el proyecto de Firebase en Flutter:
flutterfire configure --project=fcm4flutter.
Usa las teclas de flecha y la barra espaciadora para seleccionar las plataformas, o bien presiona Intro para usar las predeterminadas.
En este codelab, se usan las plataformas predeterminadas (Android, iOS y Web), pero solo puedes seleccionar una o dos plataformas. Si se te solicita el ID del paquete de iOS, ingresa com.flutter.fcm.fcmflutter
o tu propio ID del paquete de iOS en el formato [company domain name].[project name]
. Una vez completado el comando, actualiza la página de Firebase console. Verás que se crearon apps para las plataformas seleccionadas en el proyecto de Firebase.
Con este comando, se genera un archivo firebase_options.dart
en el directorio lib
, que contiene todas las opciones necesarias para la inicialización.
Configura Cloud Messaging para iOS
- Navega a la página del desarrollador de Apple y haz clic en Crear una clave en la pestaña Claves.
- Ingresa el nombre de la clave y marca Servicios de notificaciones push de Apple (APN).
- Descarga el archivo de claves, que tiene una extensión de archivo
.p8
. - En Firebase console, navega a la Configuración del proyecto del proyecto y elige la pestaña Cloud Messaging.
- Sube el archivo de claves de APNS para la app para iOS en la pestaña Cloud Messaging. Ingresa el ID de clave de APNS de la pestaña Cloud Messaging y el ID de equipo, que se encuentra en el centro de membresías de Apple.
4. Preparación para FCM
Para que una app pueda recibir mensajes de FCM, debe hacer lo siguiente:
- Inicializa FlutterFire.
- Solicita permisos de notificaciones.
- Regístrate en FCM para obtener un token de registro.
Inicialización
Para inicializar el servicio, reemplaza la función principal (lib/main.dart
) por este código:
// core Flutter primitives
import 'package:flutter/foundation.dart';
// core FlutterFire dependency
import 'package:firebase_core/firebase_core.dart';
// generated by
flutterfire configure
import 'firebase_options.dart';
// FlutterFire's Firebase Cloud Messaging plugin
import 'package:firebase_messaging/firebase_messaging.dart';
// TODO: Add stream controller
// TODO: Define the background message handler
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
// TODO: Request permission
// TODO: Register with FCM
// TODO: Set up foreground message handler
// TODO: Set up background message handler
runApp(MyApp());
}
Luego, ejecuta Tools -> Flutter -> Flutter Pub Get en Android Studio para cargar los paquetes agregados en Configura FlutterFire, y muestra el código con la configuración adecuada de Intellisense en Android Studio.
De esta manera, se inicializa FlutterFire para la plataforma actual DefaultFirebaseOptions.currentPlatform
, que se importa desde el archivo firebase_options.dart
generado. Ten en cuenta que initializeApp
es una función asíncrona y la palabra clave await
garantiza que la inicialización se complete antes de ejecutar la aplicación.
Solicitar permiso
La app debe solicitarle permiso al usuario para recibir notificaciones. El método requestPermission
que proporciona firebase_messaging
muestra un diálogo o una ventana emergente en la que se le solicita al usuario que permita o rechace el permiso.
Primero, copia este código en la función principal debajo del comentario TODO: Request permission
. El objeto settings
que se muestra indica si el usuario otorgó permiso. Recomendamos que solicites permiso solo cuando el usuario necesite usar una función que requiera acceso (p.ej., cuando el usuario active las notificaciones en la configuración de la app). En este codelab, solicitamos permiso en el inicio de la app para mayor simplicidad.
final messaging = FirebaseMessaging.instance;
final settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
if (kDebugMode) {
print('Permission granted: ${settings.authorizationStatus}');
}
A continuación, en la barra de herramientas de Android Studio, selecciona Chrome (web)
en el selector de objetivos y vuelve a ejecutar la app.
A continuación, se abrirá una pestaña de Chrome con una ventana emergente en la que se solicitará permiso. Si haces clic en Allow
, verás un registro en la consola de Android Studio: Permission granted: AuthorizationStatus.authorized
. Después de permitir o bloquear la solicitud de permiso, tu respuesta se almacena junto con tu app en el navegador y no se vuelve a mostrar la ventana emergente. Ten en cuenta que, cuando vuelvas a ejecutar la app web en Android Studio, es posible que se te solicite el permiso de nuevo.
Registro
Copia este código en la función principal debajo del comentario TODO: Register with FCM
para registrarte en FCM. La llamada getToken
muestra un token de registro que el servidor de apps o el entorno de servidor de confianza pueden usar para enviar mensajes a los usuarios.
// It requests a registration token for sending messages to users from your App server or other trusted server environment.
String? token = await messaging.getToken();
if (kDebugMode) {
print('Registration Token=$token');
}
En la barra de herramientas de Android Studio, selecciona un dispositivo Android y ejecuta la app. En la consola de Android Studio, el token de registro se imprime de la siguiente manera:
I/flutter ( 3717): Permission granted: AuthorizationStatus.authorized I/flutter ( 3717): Registration Token=dch. . . D2P:APA9. . .kbb4
Cópiala a un editor de texto, ya que lo usarás para enviar mensajes más tarde.
uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library [:firebase_messaging]
Pasos adicionales para recibir mensajes en la Web
Las apps web necesitan dos pasos adicionales para obtener el token de registro y escuchar los mensajes entrantes. La Web debe pasar una clave VAPID a getToken
para autorizar las solicitudes de envío a los servicios push web compatibles.
Primero, abre la pestaña Cloud Messaging del proyecto de Firebase en Firebase console, desplázate hacia abajo hasta la sección Configuración web para encontrar el par de claves existente o generar uno nuevo. Haz clic en el botón destacado para copiar la clave y usarla como vapidKey.
A continuación, reemplaza el código de registro en la sección Registro por este código y, luego, actualiza la vapidKey:
// TODO: replace with your own VAPID key
const vapidKey = "<YOUR_PUBLIC_VAPID_KEY_HERE>";
// use the registration token to send messages to users from your trusted server environment
String? token;
if (DefaultFirebaseOptions.currentPlatform == DefaultFirebaseOptions.web) {
token = await messaging.getToken(
vapidKey: vapidKey,
);
} else {
token = await messaging.getToken();
}
if (kDebugMode) {
print('Registration Token=$token');
}
Luego, crea un archivo firebase-messaging-sw.js
debajo del directorio web/
en la raíz de tu proyecto. Copia lo siguiente en firebase-messaging-sw.js
para permitir que la app web reciba eventos onMessage
. Consulta Configurar opciones de notificación en el service worker para obtener más información.
importScripts("https://www.gstatic.com/firebasejs/9.6.10/firebase-app-compat.js");
importScripts("https://www.gstatic.com/firebasejs/9.6.10/firebase-messaging-compat.js");
// todo Copy/paste firebaseConfig from Firebase Console
const firebaseConfig = {
apiKey: "...",
authDomain: "...",
databaseURL: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "...",
};
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
// todo Set up background message handler
Luego, en Configuración del proyecto -> pestaña General, desplázate hacia abajo y busca la app web, copia la sección de código firebaseConfig
y pégala en firebase-messaging-sw.js
.
Por último, en la barra de herramientas de Android Studio, selecciona Chrome (web)
en el selector de destino y ejecuta la app. En la consola de Android Studio, el token de registro se imprime de la siguiente manera:
Debug service listening on ws://127.0.0.1:61538/BLQQ3Fg-h7I=/ws Permission granted: AuthorizationStatus.authorized Registration Token=fH. . .ue:APA91. . .qwt3chpv
Copia el token de registro en un editor de texto para poder usarlo para enviar mensajes más tarde.
Pasos adicionales para recibir mensajes en iOS
Para recibir mensajes de FCM, los dispositivos iOS deben habilitar las notificaciones push y los modos en segundo plano en Xcode:
- En Android Studio, haz clic con el botón derecho en el nombre del proyecto y selecciona Flutter -> Open iOS module in Xcode.
- Después de iniciar Xcode, habilita las notificaciones push y los modos en segundo plano en la pestaña Signing & Capabilities para el destino del proyecto. Consulta Configura tu app para obtener más información.
- En la barra de herramientas de Android Studio, selecciona un dispositivo iOS en el selector de destino y ejecuta la app. Después de que se otorgue el permiso de notificación, se imprimirá el token de registro en la consola de Android Studio.
Felicitaciones, registraste correctamente tu app en FCM. Ya puedes recibir mensajes, como se describe en la siguiente sección.
5. Recibe mensajes de FCM
Configura controladores de mensajes
La app necesita controlar los eventos onMessage
cuando llegan los mensajes mientras la app está en modo en primer plano y los eventos onBackgroundMessage
cuando la app está en segundo plano.
Controlador de mensajes en primer plano
Primero, agrega un controlador de transmisión después del comentario TODO: Add stream controller
en el archivo main.dart
para pasar mensajes del controlador de eventos a la IU.
import 'package:rxdart/rxdart.dart';
// used to pass messages from event handler to the UI
final _messageStreamController = BehaviorSubject<RemoteMessage>();
Para agregar la dependencia rxdart, ejecuta este comando desde el directorio del proyecto: flutter pub add rxdart
.
A continuación, ejecuta Herramientas -> Flutter -> Flutter Pub Get en Android Studio para cargar el paquete rxdart.dart
y mostrar el código con la configuración de Intellisense adecuada en Android Studio.
Luego, agrega un controlador de eventos para escuchar los mensajes en primer plano después del comentario TODO: Set up foreground message handler
. Imprime registros y publica el mensaje en el controlador de transmisión.
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
if (kDebugMode) {
print('Handling a foreground message: ${message.messageId}');
print('Message data: ${message.data}');
print('Message notification: ${message.notification?.title}');
print('Message notification: ${message.notification?.body}');
}
_messageStreamController.sink.add(message);
});
Después, reemplaza el widget de estado original en el archivo main.dart
por este código, que agrega un suscriptor al controlador de transmisión en el widget de estado y muestra el último mensaje en el widget.
class _MyHomePageState extends State<MyHomePage> {
String _lastMessage = "";
_MyHomePageState() {
_messageStreamController.listen((message) {
setState(() {
if (message.notification != null) {
_lastMessage = 'Received a notification message:'
'\nTitle=${message.notification?.title},'
'\nBody=${message.notification?.body},'
'\nData=${message.data}';
} else {
_lastMessage = 'Received a data message: ${message.data}';
}
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Last message from Firebase Messaging:',
style: Theme.of(context).textTheme.titleLarge),
Text(_lastMessage, style: Theme.of(context).textTheme.bodyLarge),
],
),
),
);
}
}
Controlador de mensajes en segundo plano para iOS y Android
El controlador onBackgroundMessage
maneja los mensajes mientras la app está en segundo plano. El controlador debe ser una función de nivel superior. La IU se puede actualizar cuando la aplicación pasa a primer plano mediante la administración de los mensajes (consulta Cómo controlar la interacción) o la sincronización con el servidor de aplicaciones.
Crea la función de controlador después del comentario TODO: Define the background message handler
fuera de la función principal y llámala allí después del comentario TODO: Set up background message handler
.
// TODO: Define the background message handler
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
if (kDebugMode) {
print("Handling a background message: ${message.messageId}");
print('Message data: ${message.data}');
print('Message notification: ${message.notification?.title}');
print('Message notification: ${message.notification?.body}');
}
}
void main() {
...
// TODO: Set up background message handler
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
Controlador de mensajes en segundo plano para la Web
A partir de la versión 11.2.8 de FlutterFire de firebase_messaging, el manejo de mensajes en segundo plano en plataformas basadas en la Web requiere un flujo diferente. Por lo tanto, debes agregar un controlador de mensajes independiente en el service worker web/firebase-messaging-sw.js
.
messaging.onBackgroundMessage((message) => {
console.log("onBackgroundMessage", message);
});
Configura el servidor de apps
- Importa el código del servidor de partida. Para ello, abre el proyecto https://github.com/FirebaseExtended/firebase_fcm_flutter/tree/main/server en Android Studio. El servidor es un proyecto de Java basado en Gradle que depende del SDK firebase-admin, el cual proporciona la funcionalidad de envío de mensajes de FCM.
- Configura una cuenta de servicio de Firebase que permita que el SDK de Firebase Admin autorice llamadas a las API de FCM. Abre la Configuración del proyecto en Firebase console y selecciona la pestaña Cuentas de servicio. Elige "Java" y haz clic en
Generate new private key
para descargar el fragmento de configuración. - Cambia el nombre del archivo a
service-account.json
y cópialo en la ruta de accesosrc/main/resources
del proyecto de servidor.
Envía un mensaje de prueba
En el archivo FcmSender.java
, sendMessageToFcmRegistrationToken
redacta un mensaje de notificación con una carga útil de datos. El token de registro se dirige a la instancia de la app a la que se envía el mensaje.
private static void sendMessageToFcmRegistrationToken() throws Exception {
String registrationToken = "REPLACE_WITH_FCM_REGISTRATION_TOKEN";
Message message =
Message.builder()
.putData("FCM", "https://firebase.google.com/docs/cloud-messaging")
.putData("flutter", "https://flutter.dev/")
.setNotification(
Notification.builder()
.setTitle("Try this new app")
.setBody("Learn how FCM works with Flutter")
.build())
.setToken(registrationToken)
.build();
FirebaseMessaging.getInstance().send(message);
System.out.println("Message to FCM Registration Token sent successfully!!");
}
- Copia el token de registro de Android que copiaste de la sección Registro y pégalo en el valor de la variable
registrationToken
. - Haz clic en Run para ejecutar la función principal y enviar el mensaje al usuario a través de FCM.
Cuando la app para Android está en segundo plano, el mensaje aparece en la bandeja de notificaciones.
Cuando la app para Android esté en primer plano, verás el siguiente registro en la consola de Android Studio: "Handle un mensaje en primer plano". El contenido del mensaje también se muestra en la IU porque esta está suscrita al controlador de transmisión para mensajes nuevos.
Si pegas el token de registro y envías el mensaje desde el servidor de apps o desde otro entorno de servidor de confianza, verás un comportamiento similar al siguiente:
- Cuando la aplicación web esté en segundo plano (es decir, cuando esté oculta en otra ventana o en otra pestaña activa), verás una notificación web.
- Cuando la aplicación web esté en primer plano, podrás ver el registro en la consola de Chrome haciendo clic con el botón derecho en la Web y seleccionando
Inspect
. El contenido del mensaje también se muestra en la IU.
6. Cómo enviar un mensaje por tema
La función de anulación de la plataforma de la API de HTTP v1 de FCM permite que las solicitudes de envío de mensajes tengan comportamientos diferentes en distintas plataformas. Un caso de uso de esta función es mostrar diferentes contenidos de mensajes de notificación según la plataforma. La función es la más utilizada cuando se segmenta para varios dispositivos (que pueden abarcar varias plataformas) con mensajes por temas. En esta sección, se explican los pasos que debes seguir para hacer que tu app reciba un mensaje a tema personalizado para cada plataforma.
Suscríbete a un tema desde el cliente
Para suscribirte a un tema, llama al método messaging.subscribeToTopic
al final de la función principal en el archivo main.dart
de la app de Flutter.
// subscribe to a topic.
const topic = 'app_promotion';
await messaging.subscribeToTopic(topic);
[Opcional] Suscríbete a un tema desde el servidor para la Web
Puedes omitir esta sección si no estás desarrollando en la plataforma web.
El SDK de FCM JS actualmente no admite la suscripción a temas del cliente. En su lugar, puedes suscribirte mediante la API de administración de temas del servidor del SDK de Admin. En este código, se muestra la suscripción a temas del servidor con el SDK de Admin de Java.
private static void subscribeFcmRegistrationTokensToTopic() throws Exception {
List<String> registrationTokens =
Arrays.asList(
"REPLACE_WITH_FCM_REGISTRATION_TOKEN"); // TODO: add FCM Registration Tokens to
// subscribe
String topicName = "app_promotion";
TopicManagementResponse response = FirebaseMessaging.getInstance().subscribeToTopic(registrationTokens, topicName);
System.out.printf("Num tokens successfully subscribed %d", response.getSuccessCount());
}
Abre el servidor de apps y haz clic en Run para ejecutar la función principal en el archivo FcmSubscriptionManager.java
:
Enviar un mensaje con anulaciones de la plataformaa un tema
Ya tienes todo listo para enviar un mensaje de anulación de la plataforma de temas. En el siguiente fragmento de código:
- Creas una solicitud de envío con un mensaje base y título “
A new app is available
”. - El mensaje genera una notificación en pantalla con el título "
A new app is available
" en iOS y plataformas web. - El mensaje genera una notificación en pantalla con el título "
A new Android app is available
" en dispositivos Android.
private static void sendMessageToFcmTopic() throws Exception {
String topicName = "app_promotion";
Message message =
Message.builder()
.setNotification(
Notification.builder()
.setTitle("A new app is available")
.setBody("Check out our latest app in the app store.")
.build())
.setAndroidConfig(
AndroidConfig.builder()
.setNotification(
AndroidNotification.builder()
.setTitle("A new Android app is available")
.setBody("Our latest app is available on Google Play store")
.build())
.build())
.setTopic("app_promotion")
.build();
FirebaseMessaging.getInstance().send(message);
System.out.println("Message to topic sent successfully!!");
}
En la función principal del archivo FcmSender.java
, quita el comentario sendMessageToFcmTopic();
. Haz clic en Ejecutar para enviar el mensaje al tema.
7. Resumen y próximos pasos
En resumen, aprendiste sobre el desarrollo de apps multiplataforma participativas con Flutter y FCM, lo que incluye la configuración del entorno, la integración de dependencias y la recepción y envío de mensajes. Para profundizar más en el tema, consulta los siguientes materiales:
Codelabs
- Para obtener más información sobre cómo funciona Flutter con otros productos de Firebase, incluida la autenticación de usuarios y la sincronización de datos, consulta Conoce Firebase para Flutter.
- Para obtener más información sobre FCM, incluidos los mensajes y temas desde la app, consulta Usa FCM y FIAM para enviar mensajes a los usuarios y Tu primer mensaje push multicast con temas de FCM