1. Introdução
Última atualização: 04/04/2022
Este codelab mostra o processo de desenvolvimento de um app multiplataforma com o Firebase Cloud Messaging (FCM) usando o Flutter. Você vai escrever uma parte da implementação do app e depois criar e executar sem problemas em três plataformas: Android, iOS e Web. Você também vai aprender a integrar o FCM no Flutter e a escrever código para receber e enviar mensagens. Por fim, o codelab apresenta o recurso de blocos específicos da plataforma da API HTTP v1 do FCM, que permite enviar uma mensagem com comportamentos diferentes em plataformas diferentes.
Pré-requisito
Conhecimentos básicos sobre o Flutter.
O que você aprenderá
- Como configurar e criar um app Flutter.
- Como adicionar dependências do FCM.
- Como enviar mensagens únicas do FCM para seu app.
- Como enviar mensagens de tópico do FCM para seu app.
O que é necessário
- A versão estável mais recente do Android Studio configurada com os plug-ins Dart e Flutter.
É possível executar o codelab usando qualquer um dos seguintes dispositivos:
- Um dispositivo Android físico conectado ao computador.
- Um emulador Android (consulte Executar apps no Android Emulator).
- Um navegador da sua escolha, como o Chrome.
Se quiser executar o codelab usando a plataforma iOS, você vai precisar de um dispositivo iOS, uma conta de desenvolvedor da Apple e um dispositivo macOS com o XCode instalado.
2. Configuração do Flutter
Se você já tiver um ambiente de desenvolvimento do Flutter configurado, pule esta seção.
Para configurar um ambiente de desenvolvimento do Flutter, siga estas etapas:
- Baixe e instale o Flutter no seu sistema operacional: Instalar | Flutter
- Verifique se a ferramenta Flutter foi adicionada ao seu caminho.
- Configure seu editor para o Flutter conforme mostrado em Configurar um editor | Flutter. Instale os plug-ins do Flutter e do Dart para seu editor. No restante do codelab, você vai usar o Android Studio.
- Na linha de comando, execute
flutter doctor
, que verifica sua configuração e lista as dependências ausentes que precisam ser corrigidas. Siga as instruções para corrigir dependências importantes ausentes. Algumas dependências podem não ser necessárias. Por exemplo, se você não for desenvolver para iOS, uma dependência do CocoaPods ausente não será um problema de bloqueio. - Execute este comando para criar o app Flutter no diretório
fcmflutter
flutter create --org com.flutter.fcm --project-name fcmflutter fcmflutter
e mude parafcmflutter
.
- No Android Studio, acesse File -> Open, encontre o caminho do seu app Flutter e clique em Open para abrir o projeto no Android Studio. O código do app está no arquivo
lib/main.dart
.
Na barra de ferramentas do Android Studio, clique na seta para baixo e selecione um dispositivo Android. Se o seletor de destino estiver vazio, instale dispositivos Android virtuais, o navegador Chrome ou o simulador do iOS se preferir iniciar o app em um navegador da Web ou dispositivo iOS. Talvez seja necessário iniciar o dispositivo manualmente e atualizar a lista para encontrar o dispositivo de destino.
Clique em Executar para iniciar o app.
Parabéns! Você criou um app do Flutter.
3. Configuração do Firebase e do FlutterFire
Para desenvolver um app que se integre ao Firebase Cloud Messaging usando o Flutter, você precisa do seguinte:
- um projeto do Firebase;
- Uma CLI do Firebase funcional.
- Uma instalação do FlutterFire.
- Um app configurado e gerado com
flutterfire configure
.
Criar um projeto do Firebase
Se você já tiver um projeto do Firebase, pule esta etapa.
- Faça login no console do Firebase usando sua Conta do Google.
- Clique no botão para criar um projeto e insira um nome (por exemplo,
fcm4flutter
).
- Clique em Continuar.
- Se solicitado, leia e aceite os Termos do Firebase e clique em Continuar.
- (Opcional) Ative a assistência de IA no console do Firebase (chamada de "Gemini no Firebase").
- Neste codelab, você não precisa do Google Analytics. Portanto, desative a opção do Google Analytics.
- Clique em Criar projeto, aguarde o provisionamento e clique em Continuar.
Parabéns! Você criou um projeto do Firebase.
Configurar a CLI do Firebase
Se você já tiver a CLI do Firebase configurada, pule esta etapa.
Acesse a referência da Firebase CLI para fazer o download e instalar a CLI. Faça login no Firebase com sua Conta do Google usando o seguinte comando:
firebase login
Configurar o FlutterFire
- Instale o plug-in FlutterFire usando o comando:
flutter pub add firebase_core
- Instale o plug-in do FCM:
flutter pub add firebase_messaging
- Configure a CLI do FlutterFire:
dart pub global activate flutterfire_cli
- Configure o projeto do Firebase no Flutter:
flutterfire configure --project=fcm4flutter.
Use as teclas de seta e a barra de espaço para selecionar as plataformas ou pressione "Enter" para usar as plataformas padrão.
Este codelab usa as plataformas padrão (Android, iOS e Web), mas você pode selecionar apenas uma ou duas. Se for solicitado o ID do pacote iOS, insira com.flutter.fcm.fcmflutter
ou seu próprio ID do pacote iOS no formato [company domain name].[project name]
. Depois que o comando for concluído, atualize a página do console do Firebase. Você vai notar que ele criou apps para as plataformas selecionadas no projeto do Firebase.
Esse comando gera um arquivo firebase_options.dart
no diretório lib
, que contém todas as opções necessárias para a inicialização.
Configurar o Cloud Messaging para iOS
- Acesse a página de desenvolvedores da Apple e clique em Criar uma chave na guia Chaves.
- Insira o nome da chave e marque Serviços de notificações push da Apple (APNs).
- Faça o download do arquivo de chave, que tem uma extensão
.p8
. - No Console do Firebase, acesse as Configurações do projeto e escolha a guia Cloud Messaging.
- Faça upload do arquivo de chave do APNs para o app iOS na guia Cloud Messaging. Insira o ID da chave do APNs na guia Cloud Messaging e o ID da equipe, que pode ser encontrado no centro de membros da Apple.
4. Preparação do FCM
Antes de um app receber mensagens do FCM, ele precisa:
- Inicialize o FlutterFire.
- Solicite permissões de notificações.
- Registre-se no FCM para receber um token de registro.
Inicialização
Para inicializar o serviço, substitua a função 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());
}
Em seguida, execute Tools -> Flutter -> Flutter Pub Get no Android Studio para carregar os pacotes adicionados em Configurar o FlutterFire e mostrar o código com a configuração adequada do Intellisense no Android Studio.
Isso inicializa o FlutterFire para a plataforma atual DefaultFirebaseOptions.currentPlatform
, que é importada do arquivo firebase_options.dart
gerado. Observe que initializeApp
é uma função assíncrona, e a palavra-chave await
garante que a inicialização seja concluída antes da execução do aplicativo.
Solicitar permissão
O app precisa pedir permissão ao usuário para receber notificações. O método requestPermission
fornecido por firebase_messaging
mostra uma caixa de diálogo ou um pop-up pedindo que o usuário permita ou negue a permissão.
Primeiro, copie este código para a função principal abaixo do comentário TODO: Request permission
. O settings
retornado informa se o usuário concedeu permissão. Recomendamos pedir permissão apenas quando o usuário precisar usar um recurso que exija acesso (por exemplo, quando ele ativar as notificações nas configurações do app). Neste codelab, pedimos permissão na inicialização do app para simplificar.
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}');
}
Em seguida, na barra de ferramentas do Android Studio, selecione Chrome (web)
no seletor de destino e execute o app novamente.
Em seguida, uma guia do Chrome é aberta com um pop-up pedindo permissão. Se você clicar em Allow
, um registro vai aparecer no console do Android Studio: Permission granted: AuthorizationStatus.authorized
. Depois que você permite ou bloqueia a solicitação de permissão, sua resposta é armazenada com o app no navegador, e o pop-up não é mostrado novamente. Quando você executar o web app novamente no Android Studio, talvez seja necessário conceder a permissão outra vez.
Registro
Copie esse código para a função principal abaixo do comentário TODO: Register with FCM
para registrar no FCM. A chamada getToken
retorna um token de registro que pode ser usado pelo servidor do app ou ambiente de servidor confiável para enviar mensagens aos usuários.
// 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');
}
Na barra de ferramentas do Android Studio, selecione um dispositivo Android e execute o app. No console do Android Studio, o token de registro é impresso assim:
I/flutter ( 3717): Permission granted: AuthorizationStatus.authorized I/flutter ( 3717): Registration Token=dch. . . D2P:APA9. . .kbb4
Copie para um editor de texto, já que você vai usar esse valor para enviar mensagens mais tarde.
uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library [:firebase_messaging]
Etapas extras para receber mensagens na Web
Os apps da Web precisam de duas etapas extras para receber o token de registro e detectar mensagens recebidas. A Web precisa transmitir uma chave VAPID para o getToken
para autorizar solicitações de envio a serviços de push da Web compatíveis.
Primeiro, abra a guia Cloud Messaging do projeto do Firebase no console do Firebase, role para baixo até a seção Configuração da Web para encontrar o par de chaves atual ou gerar um novo. Clique no botão destacado para copiar a chave e usá-la como uma vapidKey.
Em seguida, substitua o código de registro na seção "Registro" por este código e atualize o 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');
}
Em seguida, crie um arquivo firebase-messaging-sw.js
abaixo do diretório web/
na raiz do projeto. Copie o seguinte para firebase-messaging-sw.js
e permita que o app da Web receba eventos onMessage
. Consulte Como configurar opções de notificação no service worker para mais informações.
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
Depois disso, em Configurações do projeto -> guia Geral, role a tela para baixo e encontre o Web App, copie a seção de código firebaseConfig
e cole em firebase-messaging-sw.js
.
Por fim, na barra de ferramentas do Android Studio, selecione Chrome (web)
no seletor de destino e execute o app. No console do Android Studio, o token de registro é impresso assim:
Debug service listening on ws://127.0.0.1:61538/BLQQ3Fg-h7I=/ws Permission granted: AuthorizationStatus.authorized Registration Token=fH. . .ue:APA91. . .qwt3chpv
Copie o token de registro em um editor de texto para usar depois no envio de mensagens.
Etapas extras para receber mensagens no iOS
Para receber mensagens do FCM, os dispositivos iOS precisam ativar as Notificações push e os Modos de segundo plano no Xcode:
- No Android Studio, clique com o botão direito do mouse no nome do projeto e selecione Flutter -> Open iOS module in Xcode.
- Depois que o Xcode for iniciado, ative as notificações push e os modos em segundo plano na guia Assinatura e recursos do destino do projeto. Consulte Configurar seu app para mais informações.
- Na barra de ferramentas do Android Studio, selecione um dispositivo iOS no seletor de destino e execute o app. Depois que a permissão de notificação for concedida, o token de registro será impresso no console do Android Studio.
Parabéns! Você registrou seu app no FCM. Agora você pode receber mensagens, conforme descrito na próxima seção.
5. Receber mensagens do FCM
Configurar manipuladores de mensagens
O app precisa processar eventos onMessage
quando as mensagens chegam enquanto ele está em primeiro plano e eventos onBackgroundMessage
quando ele está em segundo plano.
Processador de mensagens em primeiro plano
Primeiro, adicione um controlador de fluxo após o comentário TODO: Add stream controller
no arquivo main.dart
para transmitir mensagens do gerenciador de eventos à interface.
import 'package:rxdart/rxdart.dart';
// used to pass messages from event handler to the UI
final _messageStreamController = BehaviorSubject<RemoteMessage>();
Para adicionar a dependência rxdart, execute este comando no diretório do projeto: flutter pub add rxdart
.
Em seguida, execute Tools -> Flutter -> Flutter Pub Get no Android Studio para carregar o pacote rxdart.dart
e mostrar o código com as configurações adequadas do Intellisense no Android Studio.
Em seguida, adicione um gerenciador de eventos para detectar mensagens em primeiro plano após o comentário TODO: Set up foreground message handler
. Ele imprime registros e publica a mensagem no controlador de stream.
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);
});
Depois disso, substitua o widget State original no arquivo main.dart
por este código, que adiciona um assinante ao controlador de fluxo no widget State e mostra a última mensagem no 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),
],
),
),
);
}
}
Processador de mensagens em segundo plano para Android/iOS
As mensagens são processadas pelo gerenciador onBackgroundMessage
enquanto o app está em segundo plano. O manipulador precisa ser uma função de nível superior. A interface pode ser atualizada quando o app é trazido para o primeiro plano ao processar as mensagens (consulte Processamento de interação) ou sincronizar com o servidor do app.
Crie a função de gerenciador após o comentário TODO: Define the background message handler
fora da função principal e chame-a na função principal após o comentário 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());
}
Gerenciador de mensagens em segundo plano para a Web
A partir da versão 11.2.8 do firebase_messaging do FlutterFire, o processamento de mensagens em segundo plano em plataformas baseadas na Web exige um fluxo diferente. Portanto, é necessário adicionar um manipulador de mensagens separado no service worker web/firebase-messaging-sw.js
.
messaging.onBackgroundMessage((message) => {
console.log("onBackgroundMessage", message);
});
Configurar o servidor de apps
- Importe o código inicial do servidor abrindo o projeto https://github.com/FirebaseExtended/firebase_fcm_flutter/tree/main/server no Android Studio. O servidor é um projeto Java baseado em Gradle com uma dependência do SDK firebase-admin, que oferece funcionalidade de envio de mensagens do FCM.
- Configure uma conta de serviço do Firebase que permita ao SDK Admin do Firebase autorizar chamadas para as APIs do FCM. Abra as Configurações do projeto no console do Firebase e selecione a guia Contas de serviço. Escolha "Java" e clique em
Generate new private key
para baixar o snippet de configuração. - Renomeie o arquivo como
service-account.json
e copie para o caminhosrc/main/resources
do projeto do servidor.
Enviar uma mensagem de teste
No arquivo FcmSender.java
, sendMessageToFcmRegistrationToken
cria uma mensagem de notificação com um payload de dados. O token de registro tem como destino a instância do app para onde a mensagem é enviada.
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!!");
}
- Copie o token de registro do Android na seção "Registro" e cole-o no valor da variável
registrationToken
. - Clique em Executar
para executar a função principal e enviar a mensagem ao usuário pelo FCM.
Quando o app Android está em segundo plano, a mensagem aparece na bandeja de notificações.
Quando o app Android estiver em primeiro plano, um registro vai aparecer no console do Android Studio: "Handling a foreground message". O conteúdo da mensagem também é mostrado na interface porque ela está inscrita no controlador de fluxo para novas mensagens.
Se você colar o token de registro e enviar a mensagem do servidor de apps ou de outro ambiente de servidor confiável, vai notar um comportamento semelhante:
- Quando o web app está em segundo plano (ou seja, quando ele está oculto por outra janela ou outra guia está ativa), você vê uma notificação da Web.
- Quando o web app está em primeiro plano, é possível ver o registro no console do Chrome clicando com o botão direito do mouse na Web e selecionando
Inspect
. O conteúdo da mensagem também é exibido na interface.
6. Enviar uma mensagem de tópico
Com o recurso de substituição de plataforma da API HTTP v1 do FCM, uma solicitação de envio de mensagem pode ter comportamentos diferentes em plataformas diferentes. Um caso de uso desse recurso é mostrar conteúdo de mensagens de notificação diferente com base na plataforma. O recurso é mais usado ao segmentar vários dispositivos (que podem abranger várias plataformas) com mensagens de tópico. Nesta seção, você vai aprender a fazer com que seu app receba uma mensagem de tópico personalizada para cada plataforma.
Inscrever-se em um tópico no cliente
Para se inscrever em um tópico, chame o método messaging.subscribeToTopic
no final da função principal do arquivo main.dart
do app Flutter.
// subscribe to a topic.
const topic = 'app_promotion';
await messaging.subscribeToTopic(topic);
[Opcional] Inscrever-se em um tópico do servidor para a Web
Pule esta seção se você não estiver desenvolvendo na plataforma da Web.
No momento, o SDK do FCM JS não é compatível com a inscrição em tópicos do lado do cliente. Em vez disso, você pode fazer a inscrição usando a API de gerenciamento de tópicos do lado do servidor do SDK Admin. Este código ilustra a inscrição em tópicos do lado do servidor com o SDK Admin para 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());
}
Abra o servidor de apps e clique em Executar para executar a função principal no arquivo
FcmSubscriptionManager.java
:
Enviar uma mensagem com substituições de plataformas para um tópico
Agora você pode enviar uma mensagem de substituição da plataforma de tópicos. No snippet de código a seguir:
- Você cria uma solicitação de envio com uma mensagem básica e o título "
A new app is available
". - A mensagem gera uma notificação de exibição com o título "
A new app is available
" nas plataformas iOS e Web. - A mensagem gera uma notificação de exibição com o título "
A new Android app is available
" em 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!!");
}
Na função principal do arquivo FcmSender.java
, remova o comentário de sendMessageToFcmTopic();
. Clique em Executar para enviar a mensagem do tópico.
7. Resumo e próximas etapas
Em resumo, você aprendeu sobre o desenvolvimento de apps multiplataforma envolventes usando o Flutter e o FCM, incluindo configuração de ambiente, integração de dependências e recebimento e envio de mensagens. Para mais detalhes, consulte os seguintes materiais:
Codelabs
- Para saber mais sobre como o Flutter funciona com outros produtos do Firebase, incluindo autenticação de usuários e sincronização de dados, consulte Introdução ao Firebase para Flutter.
- Para saber mais sobre o FCM, incluindo mensagens no app e tópicos, consulte Usar o FCM e as Mensagens no app para enviar mensagens aos usuários e Sua primeira mensagem push multicast usando tópicos do FCM.