Push Notification no Flutter (Firebase)

Integrando o seu app Flutter com o Firebase

Gabriel Mello de Oliveira
6 min readMar 3, 2024
Push Notification no Flutter com Firebase

Introdução ao Push Notification

Notificações push são um tipo de mensagens pop-up (em português mensagens que “estouram” na tela) que alertam os usuários de aplicativos sobre o que está acontecendo no aplicativo. Elas também são uma forma importante de ampliar o engajamento dos usuários em seu aplicativo.

Por exemplo, digamos que um usuário esquece do aplicativo depois de instalado. Então, você pode usar notificações push como um mecanismo para recuperar e manter o interesse dos usuários. As notificações push também podem ajudar a direcionar tráfego para o aplicativo.

Configurações no Firebase

O Firebase Cloud Messaging é um serviço oferecido pela Firebase, que permite que você envie notificações para seus usuários. Você pode definir várias configurações para enviar diferentes notificações para públicos diferentes com base em tempo e rotina.

Por causa de todos esses benefícios, nós vamos usar esse serviço para enviar notificações para nosso aplicativo Flutter.

O nosso primeiro passo é criar uma conta no Firebase (https://firebase.google.com).

Tela inicial do Firebase

Deve ser criado um novo projeto no Firebase.

Tela de criação de projetos Firebase
Tela de criação de um projeto Firebase
Tela do projeto criado

Após o projeto criado, você é direcionado para a tela principal do projeto no Firebase com opções para configurações do firebase nas plataformas, sendo assim vamos escolher o Flutter.

Tela principal de um projeto Firebase, sem a configuração para alguma plataforma

Configurando o Flutter no Firebase

Após a criação do projeto, vamos configurar a integração do Flutter com o Firebase. Quando é selecionada a plataforma, teremos as seguinte telas de configuração, mas não se preocupe, vamos realizar cada uma delas com mais detalhes logo abaixo.

Tela de integração do Firebase com o Flutter (Instalação do Firebase CLI)
Tela de integração do Firebase com o Flutter (Instalação e configuração do FlutterFire CLI)
Tela de integração do Firebase com o Flutter (Configuração do Firebase no projeto)

Instalando o Firebase CLI

Para realizar a instalação do Firebase CLI no seu ambiente, podemos entrar nesse link como referência https://firebase.google.com/docs/cli?hl=pt&authuser=0.

A instalação a seguir será realizada em ambiente windows

Tela de instalação do Firebase CLI

Aqui vamos instalar utilizando o NPM (Node Package Manager), rodando o seguinte comando.

npm install -g firebase-tools
Passo a passo de instalação do Firebase CLI com NPM

Caso não tenha o NPM instalado, você consegue realizar a instalação do Node através do seguinte link https://nodejs.org/en/download.

Para verificar se a instalação do Firebase CLI ocorreu com sucesso, abra o seu terminal e rode o seguinte comando.

firebase --version

Após a instalação, deve ser realizado o login com o Firebase, para isso rode o seguinte comando.

firebase login

Instalando o FlutterFire

O FlutterFire é uma ferramenta para auxiliar na integração do Flutter com o Firebase.

Para realizar a instalação é necessário rodar o seguinte comando.

dart pub global activate flutterfire_cli

Para verificar se a instalação do FlutterFire ocorreu com sucesso, abra o seu terminal e rode o seguinte comando.

flutterfire --version

Caso o comando flutterfire não seja encontrado, será necessário adicionar o caminho do mesmo nas variaveis de ambiente, para isso adicione o seguinte caminho na variável de ambiente PATH do usuário.

%USERPROFILE%\AppData\Local\Pub\Cache\bin

Após isso, verifique novamente se o FlutterFire está configurado corretamente. Caso tenha sucesso, entre na pasta do projeto flutter e rode o seguinte comando de configuração.

flutterfire configure --project=NOME_DO_PROJETO

Esse comando serve para configurar a integração do Firebase com o Flutter e suas plataformas em que o projeto está dando suporte.

Inicializando o Firebase

Para iniciar a integração com o Firebase, devemos inicializar o Firebase em nosso projeto.

O seguinte código deve ser adicionado na função main antes de rodar o runApp.

void main() async {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);

runApp(const MyApp());
}

É comum que ocorra um erro na inicialização do seu aplicativo, por conta da inicialização do Firebase. Para isso, precisamos inicializar o binding do widgets no Flutter, com o seguinte código.

void main() async {
WidgetsFlutterBinding.ensureInitialized();

await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);

runApp(const MyApp());
}

Essa classe WidgetsFlutterBinding é responsável por gerenciar o ciclo de vida dos widgets e a comunicação entre o código Dart e a plataforma nativa (como Android ou iOS). É essencial para o funcionamento do Flutter.

Já o método ensureInitialized verifica se a instância do WidgetsFlutterBinding já existe. Se não existir, ele cria e inicia uma nova. Se já existir, ele simplesmente retorna a instância existente.

Inicializando o FirebaseMessaging

Para trabalharmos com as push notifications, precisamos inicializar o FirebaseMessaging, fazendo a requisição de permissão do aplicativo, para lidar com notificações.

class PushNotification {
static final _firebaseMessaging = FirebaseMessaging.instance;

static Future init() async {
await _firebaseMessaging.requestPermission(
alert: true,
announcement: false,
badge: true,
sound: true,
);

final token = await _firebaseMessaging.getToken();
print('Token: $token');
}
}

No código acima, criamos uma classe PushNotification com um método init, que é responsável por fazer a requisição de permissão para o aplicativo lidar com as notificações e também para buscar o token do dispositivo para receber as notificações.

Processando o recebimento de notificação

Toda vez que recebemos uma nova notificação com o aplicativo em segundo plano, podemos processar essa notificação e realizar alguma ação, para isso precisamos adicionar uma função que fique escutando quando essa notificação chegar, da seguinte forma:

void main() async {
WidgetsFlutterBinding.ensureInitialized();

await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);

PushNotification.init();

// Função responsável por escutar a chegada de novas notificações
FirebaseMessaging.onBackgroundMessage((RemoteMessage message) async {
if (message.notification != null) {
print('Message handled in the background!');
print('Title: ${message.notification!.title}');
print('Body: ${message.notification!.body}');
}
});

runApp(const MyApp());
}

Processando a abertura de uma notificação

Toda vez que abrimos uma notificação com o aplicativo em segundo plano, podemos processar essa notificação e realizar alguma ação, para isso precisamos adicionar uma função que fique escutando quando essa notificação for aberta, da seguinte forma:

void main() async {
WidgetsFlutterBinding.ensureInitialized();

await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);

PushNotification.init();

// Função responsável por escutar a abertura de notificações
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
if (message.notification != null) {
print('Message opened in the foreground!');
print('Title: ${message.notification!.title}');
print('Body: ${message.notification!.body}');
}
});

FirebaseMessaging.onBackgroundMessage(_firebaseBackgroundMessage);

runApp(const MyApp());
}

Roteamento a partir da abertura de uma notificação

Algo muito comum, quando estamos trabalhando com push notifications, é a abertura de uma tela específica quando a notificação é aberta, por exemplo, em um aplicativo de chat, quando uma nova mensagem de uma conversa específica chega via push notification, é esperado que ao clicar nessa notificação, seja aberta a tela com a conversa específica e é isso que vamos fazer agora.

Primeiro precisamos criar uma nova tela.

class MessageScreen extends StatelessWidget {
const MessageScreen({
this.title,
this.body,
super.key
});

final String? title;
final String? body;

@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Text(title ?? 'No title'),
Text(body ?? 'No message'),
],
),
);
}
}

Após isso, criamos uma instância global do nosso navigator (início do arquivo main.dart).

final navigatorKey = GlobalKey<NavigatorState>();

Com a instância do navigator criada, devemos adicioná-la no MaterialApp, para controle da navegação.

return MaterialApp(
navigatorKey: navigatorKey,
title: 'Flutter - Push Notification',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const MyHomePage(title: 'Home Page'),
);

E na função de abertura de notificações, vamos implementar a navegação, passando os parametros necessários para aquela tela.

FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
if (message.notification != null) {
navigatorKey.currentState!.push(
MaterialPageRoute(
builder: (context) => MessageScreen(
title: message.notification!.title,
body: message.notification!.body,
),
),
);
}
}
);

Esse foi meu primeiro post aqui no medium... Não sabia sobre o que escrever mas após a criação de um conteúdo para um curso de Flutter, decidi trazer algo em que gostei do resultado e acredito que possa ajudar alguém no futuro, espero que tenham gostado e podem aguardar os próximos, muito obrigado por ter chegado até aqui 😁

--

--

Gabriel Mello de Oliveira
0 Followers

Sou um desenvolvedor apaixonado por inovação e resolução de problemas. Experiência sólida em tecnologias Javascript, .NET e Go, buscando evoluir a cada dia.