O envolvimento do usuário é crucial para o sucesso de qualquer aplicativo móvel. As notificações push ajudam a atrair a atenção do usuário e, quando implementadas corretamente em conjunto com conteúdo de alta qualidade, podem contribuir para o grande sucesso de marketing.
Neste tutorial, vamos demonstrar como integrar e entregar notificações push para um Flutter aplicativo usando um serviço incrível fornecido pelo Firebase chamado Firebase Cloud Messaging (FCM) . É grátis e fácil de começar, e você não precisa gerenciar sua infraestrutura de back-end.
Cobriremos o seguinte com exemplos detalhados e instruções passo a passo:
- O que são notificações push?
- Configuração do Firebase
- Integração do Firebase com seu aplicativo Flutter
- Integração Android
- Integração iOS
- Plug-ins Flutter
- Construindo uma IU do Flutter
- Adicionando funcionalidade push com Firebase Cloud Messaging
- Reagindo a uma notificação push
- Tratamento de notificações em segundo plano
- Notificações push oscilantes no Android e iOS
O que são notificações push?
Se você usa um smartphone, quase certamente encontrará notificações push todos os dias. Notificações push são mensagens pop-up clicáveis que aparecem nos dispositivos de seus usuários, independentemente de eles estarem usando esse aplicativo específico. Mesmo quando o dispositivo está ocioso ou o usuário está usando outro aplicativo, eles recebem notificações push, desde que o dispositivo esteja online e as permissões de notificação sejam concedidas.
Neste tutorial, usaremos Firebase Cloud Messaging para enviar notificações push.
Configuração do Firebase
Para começar a usar o Firebase , você precisa criar um novo projeto do Firebase.
Faça login em sua conta do Google, navegue até o Firebase console e clique em Adicionar projeto .
Insira um nome de projeto e clique em Continuar .
Desative o Google Analytics; não precisamos dele para nosso projeto de amostra. Em seguida, clique em Criar projeto .
Após a inicialização do projeto, clique em Continuar .
Isso o levará para a tela Visão geral do projeto . Aqui, você encontrará opções para integrar o projeto Firebase ao seu aplicativo Android e iOS.
Integração do Firebase com seu aplicativo Flutter
Nosso projeto Firebase agora está pronto para ser integrado ao aplicativo móvel. Embora estejamos usando Flutter , que é uma estrutura de plataforma cruzada, ainda temos que fazer a configuração inicial do Firebase para ambas as plataformas separadamente.
Primeiro, crie um novo aplicativo Flutter:
vibração criar notificação
A seguir, abra o projeto Flutter em seu IDE favorito.
Para abri-lo no VS Code, você pode usar o seguinte:
código de notificação
Integração Android
Para integrar seu projeto Firebase com o lado Android do aplicativo, siga as etapas abaixo.
Clique no ícone do Android na página de visão geral do projeto:
Isso levará a um formulário. Primeiro, insira o nome do pacote Android. Você pode encontrar isso em seu diretório do projeto
→ android
→ app
→ src
→ AndroidManifest.xml
. Na segunda linha, você verá o nome do seu pacote. Basta copiar e colar no formulário.
Opcionalmente, você pode escolher um apelido para seu aplicativo. Se você deixar este campo vazio, um nome de aplicativo gerado automaticamente será usado.
Você deve inserir o hash SHA-1. Passe o mouse sobre o ícone de ajuda (? ) e clique em Ver esta página . Isso o levará para a página Autenticação do seu cliente :
A partir daqui, você obterá o comando para gerar o hash SHA-1. Cole-o em seu terminal para obter o hash SHA-1 e, em seguida, copie e cole o hash gerado no formulário.
Clique em Registrar aplicativo . Isso o levará para a próxima etapa.
Baixe o arquivo google-services.json
, arraste e solte-o no diretório do projeto
→ android
→ app e, em seguida, clique em Avançar .
Siga as instruções e adicione os snippets de código na posição desejada. Em seguida, clique em Avançar .
Por fim, clique em Continuar para o console .
Com isso, você concluiu a configuração do Firebase para o lado Android do seu aplicativo.
Integração iOS
Para integrar seu projeto Firebase ao lado iOS do seu aplicativo, siga as etapas descritas abaixo.
Clique em Adicionar aplicativo presente na página de visão geral do projeto e selecione iOS :
Insira o ID do pacote iOS e seu apelido do aplicativo . Em seguida, clique em Registrar aplicativo .
Você pode encontrar o ID do pacote em ios
→ Runner.xcodeproj
→ project.pbxproj
pesquisando por “PRODUCT_BUNDLE_IDENTIFIER.”
Faça download do arquivo GoogleService-Info.plist
.
Abra a pasta ios
do diretório do projeto no Xcode. Arraste e solte o arquivo baixado na subpasta Runner
. Quando uma caixa de diálogo aparecer, certifique-se de que Copiar itens se necessário da propriedade Destino
esteja marcada e Runner esteja selecionado em Adicionar para alvos caixa. Em seguida, clique em Concluir .
Você pode fechar o Xcode agora.
Você pode pular as etapas três e quatro; eles serão gerenciados pelo plug-in Flutter Firebase, que adicionaremos em breve. Em seguida, clique em Continuar para o console .
Antes de mergulhar no código Flutter, você precisa concluir mais uma etapa no Firebase.
Vá para Configurações do projeto :
Under the General tab, enter your Support email.
Now the Firebase setup and integration are complete. Let’s move on to the Flutter code.
Flutter plugins
The Flutter plugins we require for this project are:
firebase_core
, which is required to use any Firebase service with Flutterfirebase_messaging
, which is used for receiving notifications in the appoverlay_support
, which builds overlay UI
You can get these packages from pub.dev with their latest versions. Add them to the pubspec.yaml
file of the Flutter project.
Building a Flutter UI
We’ll keep the UI of this Flutter app simple so we can focus on the push notification functionality.
The app will contain an AppBar
and some Text
widgets inside a Column
to display the notification content:
Navigate to the lib
folder from the root project directory where the Dart code is present. Replace the entire code with the following:
void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title:'Notify', theme: ThemeData( primarySwatch: Colors.deepPurple, ), debugShowCheckedModeBanner: false, home: HomePage(), ); } }
Now we have to define the HomePage
widget, which will be a StatefulWidget
, because we’ll need to update the UI as soon as a notification arrives.
class HomePage extends StatefulWidget { @override _HomePageState createState()=> _HomePageState(); } class _HomePageState extends State{ int _totalNotifications; @override void initState() { _totalNotifications=0; super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Notify'), brightness: Brightness.dark, ), body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'App for capturing Firebase Push Notifications', textAlign: TextAlign.center, style: TextStyle( color: Colors.black, fontSize: 20, ), ), SizedBox(height: 16.0), NotificationBadge(totalNotifications: _totalNotifications), SizedBox(height: 16.0), //TODO: add the notification text here ], ), ); } }
Here, we have a Scaffold
containing an AppBar
and a Column
. The column contains a basic Text
widget followed by the NotificationBadge
widget for displaying the total number of notifications received. You may have noticed the TODO
; this is where we’ll display the notification information.
The code for the NotificationBadge
is as follows:
class NotificationBadge extends StatelessWidget { final int totalNotifications; const NotificationBadge({@required this.totalNotifications}); @override Widget build(BuildContext context) { return Container( width: 40.0, height: 40.0, decoration: new BoxDecoration( color: Colors.red, shape: BoxShape.circle, ), child: Center( child: Padding( padding: const EdgeInsets.all(8.0), child: Text( '$totalNotifications', style: TextStyle(color: Colors.white, fontSize: 20), ), ), ), ); } }
Adding push functionality with Firebase Cloud Messaging
Now it’s time to add the push functionality. To start using the FCM, create an instance of FirebaseMessaging
inside the _HomePageState
widget, like this:
class _HomePageState extends State{ FirebaseMessaging _messaging=FirebaseMessaging(); //... @override Widget build(BuildContext context) { //... } }
Create a method called registerNotification()
inside the _HomePageState
class. This will initialize the Firebase app, request notification access (required only on iOS devices), and configure the messaging to receive push notifications as well as display them.
void registerNotification() async { //1. Initialize the Firebase app await Firebase.initializeApp(); //2. On iOS, this helps to take the user permissions await _messaging.requestNotificationPermissions( IosNotificationSettings( alert: true, badge: true, provisional: false, sound: true, ), ); //TODO: handle the received notifications }
In the above code, we first initialized the Firebase app, without which we won’t be able to access any Firebase services inside the app.
The method requestNotificationPermissions()
is used for taking user consent on iOS devices (if the app is run on an Android device, this is ignored).
To receive push notifications that arrive on the device, and to perform a UI change according to it, use the following code:
void registerNotification() async { PushNotification _notificationInfo; //... //For handling the received notifications _messaging.configure( onMessage: (message) async { print('onMessage received: $message'); //Parse the message received PushNotification notification=PushNotification.fromJson(message); setState(() { _notificationInfo=notification; _totalNotifications++; }); }, ); }
Here, the PushNotification
is a model class for parsing the notification content, which will be in JSON format.
The PushNotification
model class looks like this:
class PushNotification { PushNotification({ this.title, this.body, }); String title; String body; factory PushNotification.fromJson(Mapjson) { return PushNotification( title: json["notification"]["title"], body: json["notification"]["body"], ); } }
FCM generates a registration token for the client app on initial startup. It’s helpful for sending a push notification to single devices and creating device groups. You can access it by using the following code:
void registerNotification() async { //... //Used to get the current FCM token _messaging.getToken().then((token) { print('Token: $token'); }).catchError((e) { print(e); }); }
Reacting to a push notification
To show the notification on the UI, you can use the overlay_support
plugin we added earlier. You can easily create a simple or even a custom UI effect as any notification arrives on the device.
Wrap the MaterialApp
widget with the OverlaySupport
widget:
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return OverlaySupport( child: MaterialApp( //... ), ); } }
Then you can use the showSimpleNotification()
method to display the notification inside the app:
void registerNotification() async { _messaging.configure( onMessage: (message) async { //... //For displaying the notification as an overlay showSimpleNotification( Text(_notificationInfo.title), leading: NotificationBadge(totalNotifications: _totalNotifications), subtitle: Text(_notificationInfo.body), background: Colors.cyan[700], duration: Duration(seconds: 2), ); }, ); }
As you might remember, we left a TODO
to be completed where we have to show the notification data on the screen. You can use the _notificationInfo
and _totalNotifications
variables to show the information:
class _HomePageState extends State{ PushNotification _notificationInfo; int _totalNotifications; //... @override Widget build(BuildContext context) { return Scaffold( body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ //... _notificationInfo !=null ? Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'TITLE: ${_notificationInfo.title}', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 16.0, ), ), SizedBox(height: 8.0), Text( 'BODY: ${_notificationInfo.body}', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 16.0, ), ), ], ) : Container(), ], ), ); } }
As you can see, we’re displaying a Column
with two Text
widgets to show the title and body of the notification. When the _notificationInfo
is null, we just show an empty Container
.
If you try to put the app in the background, you’ll still receive the notification. But since we’ve yet to configure how to handle background notifications, you won’t see any change in the UI as you tap on the notification to open the app.
Handling background notifications
To handle background notifications, we have to define a top-level function called _firebaseMessagingBackgroundHandler()
and define the onBackgroundMessage
property inside the _messaging.configure()
method.
You can define the _firebaseMessagingBackgroundHandler()
function like this:
Future_firebaseMessagingBackgroundHandler( Map message, ) async { //Initialize the Firebase app await Firebase.initializeApp(); print('onBackgroundMessage received: $message'); }
Keep in mind that you have to define this as a top-level function, which means it should be outside of any class.
Specify the onBackgroundMessage
property:
void registerNotification() async { //For handling the received notifications _messaging.configure( //... onBackgroundMessage: _firebaseMessagingBackgroundHandler, ); }
If you just define this, you won’t be able to retrieve and show data within the app.
You have to define two more properties inside the configure()
method:
onLaunch
onResume
Here, we’ll just parse the message and update the UI state:
void registerNotification() async { //For handling the received notifications _messaging.configure( //... onLaunch: (message) async { print('onLaunch: $message'); PushNotification notification=PushNotification.fromJson(message); setState(() { _notificationInfo=notification; _totalNotifications++; }); }, onResume: (message) async { print('onResume: $message'); PushNotification notification=PushNotification.fromJson(message); setState(() { _notificationInfo=notification; _totalNotifications++; }); }, ); }
There is one more catch: the message JSON you receive when you tap on the notification to open the app will look like this:
onResume: {notification: {}, data: {collapse_key: com.souvikbiswas.notify, google.original_priority: high, google.sent_time: 1613101377789, google.delivered_priority: high, google.ttl: 2419200, from: 798605711100, click_action: FLUTTER_NOTIFICATION_CLICK, google.message_id: 0:1613101378029252%bc1b6e8ebc1b6e8e}}
Notice that the notification map is empty here; only data
is present. So if you need to pass any data to your app, you have to send it through an additional data property. We’ll cover how to send push notifications from FCM console in a bit.
To retrieve this data, you have to make a minor modification to the model class:
class PushNotification { PushNotification({ this.title, this.body, this.dataTitle, this.dataBody, }); String title; String body; String dataTitle; String dataBody; factory PushNotification.fromJson(Mapjson) { return PushNotification( title: json["notification"]["title"], body: json["notification"]["body"], dataTitle: json["data"]["title"], dataBody: json["data"]["body"], ); } }
Here, we retrieved two additional fields from the data
message.
To show them in the UI, you can make these modifications to the Text
widgets where you display that information:
Text( 'TITLE: ${_notificationInfo.title ?? _notificationInfo.dataTitle}', //... ), Text( 'BODY: ${_notificationInfo.body ?? _notificationInfo.dataBody}', //... ),
This will display the information from the data message whenever the notification message is empty.
Flutter push notifications on Android and iOS
Now that we’ve completed our example Flutter app with push notifications, it’s time to run it. To do so, we need to make some configurations to both the Android and iOS sides of the app.
Android
To run the app on your Android device, follow the steps below:
Go to android
→ app
→ build.gradle
, and enable multidex support:
android { defaultConfig { //... multiDexEnabled true } }
If handling background notifications, add the com.google.firebase:firebase-messaging
dependency to your android
→ app
→ build.gradle
.
dependencies { //... implementation'com.google.firebase:firebase-messaging:' }
Make sure you’re using the latest version of the dependency.
If handling background notifications, navigate to android
→ app
→ src
→ main
. Inside the directory with your product identifier, create a new file called Application.kt
and add the following to it:
packageimport io.flutter.app.FlutterApplication import io.flutter.plugin.common.PluginRegistry import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService class Application: FlutterApplication(), PluginRegistrantCallback { override fun onCreate() { super.onCreate() FlutterFirebaseMessagingService.setPluginRegistrant(this) } override fun registerWith(registry: PluginRegistry?) { io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin.registerWith( registry?.registrarFor( "io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")); } }
Inside android
→ app
→ src
→ main
→ AndroidManifest.xml
, add the android:name
property inside the
tag (only required if handling background notifications) and the
tag inside the
:
android:name=".Application" android:label="notify" android:icon="@mipmap/ic_launcher">
The
tag will help to retrieve the data message while a notification arrives.
iOS
If you’re running on an iOS device, you’ll need to perform some additional setup, including enabling push notifications and background modes in Xcode.
In addition, you must have an Apple Developer account. Since Firebase Cloud Messaging integrates with the Apple Push Notification service, which only works with real devices, you’ll also need access to a physical iOS device to receive push notifications.
You can find a detailed, step-by-step guide to configuring your iOS app to receive push notifications in the official FireFlutter docs.
Sending push notifications in Flutter with Firebase Cloud Messaging
You can send notifications from the Firebase Cloud Messaging (FCM) console directly. To do so, follow the steps outlined below.
Go to the Cloud Messaging section from the left menu of the project overview page and click Send your first message.
Enter a notification title, text, and name, then click Next.
Set the Target to be either your Android or iOS app, or both. Click Next.
Specify the Scheduling as “Now.” Click Next.
For a simple notification, you don’t need to provide anything in the Additional options field.
Click Review.
Click Publish to send the notification. Don’t worry about the warning at the top; it’s only telling us we haven’t set up analytics for this project.
You can send data by specifying the following in the Additional options. Here, the click_action
key with the value FLUTTER_NOTIFICATION_CLICK
is mandatory. Otherwise, your app won’t be able to retrieve the data message on the device.
Click Review, then Publish to send the data notification.
Conclusion
If you’ve made it to this point, you should have a solid understanding of what push notifications are, how to integrate push notification functionality with a Flutter app, and how to send push notifications using Firebase Cloud Messaging.
There are countless other customizations you can explore when implementing push notifications in Flutter. Check out these resources to learn more:
- GitHub repository of the example app
- Firebase Cloud Messaging docs (Flutter)
- FCM message types and structures
- More ways to send Flutter push notifications
The post Flutter push notifications with Firebase Cloud Messaging appeared first on LogRocket Blog.