💬Local Notifications

Aqui vamos mostrar como tratar as notificações que chegam no nosso app, esteja ele fechado, "minimizado" ou já aberto.

Após o seu app já estar com o Firebase configurado e as notificações habilitadas, vamos abordar como podemos tratar a chegada dessas notificações no aplicativo. Para que as notificações apareçam, quando o app não está aberto, nada precisa ser feito, porém, quando o app está aberto e alguma notificação é enviada, ela não vai aparecer. E é ai que entra o problema, e a solução também vai estar nos códigos aqui.

Foi criada uma classe para tratar as funções, no seguinte código:

class NotificationService {
  static final FirebaseMessaging _messaging = FirebaseMessaging.instance;

  final NavigationService navigationService = GetIt.I.get<NavigationService>();

  final _localNotificationsPlugin = FlutterLocalNotificationsPlugin();

  static Future<void> _requestPermission() async {
    if (Platform.isAndroid) return;

    await _messaging.requestPermission();
    await _messaging.setForegroundNotificationPresentationOptions(
      alert: true,
      badge: true,
      sound: true,
    );
  }

  Future setup() async {
    await _requestPermission();

    await initialize();

    await _configureAndroidChannel();

    await _openInitialScreenFromMessage();
  }

  Future<void> initialize() async {
    const androidSetting =
        AndroidInitializationSettings('@mipmap/launcher_icon');
    const iosSetting = DarwinInitializationSettings();

    const initSettings =
        InitializationSettings(android: androidSetting, iOS: iosSetting);

    await _localNotificationsPlugin
        .initialize(initSettings)
        .then((_) async {})
        .catchError((Object error) {
      log('Error: $error');
    });
  }

  Future<void> _configureAndroidChannel() async {
    const AndroidNotificationChannel channel = AndroidNotificationChannel(
      'BreakingCodeChannel',
      'High Importance Notifications',
      description: 'This channel is used for important notifications.',
      importance: Importance.max,
    );

    await _localNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            AndroidFlutterLocalNotificationsPlugin>()
        ?.createNotificationChannel(channel);
  }

  invokeLocalNotification(RemoteMessage remoteMessage) async {
    RemoteNotification? notification = remoteMessage.notification;
    AndroidNotification? android = remoteMessage.notification?.android;

    if (notification != null && android != null) {
      await _localNotificationsPlugin.show(
        notification.hashCode,
        notification.title,
        notification.body,
        NotificationDetails(
          android: AndroidNotificationDetails(
            'BreakingCodeChannel',
            'High Importance Notifications',
            channelDescription:
                'This channel is used for important notifications.',
            icon: android.smallIcon,
          ),
        ),
        payload: jsonEncode(remoteMessage.data),
      );
    }
  }
}

Função setup: Faz toda a inicialização necessária, chamada de permissões, etc.

Função initiliaze: Inicializa a instância FlutterLocalNotificationsPlugin que vai ser utilizada depois.

Função _configureAndroidChannel: Configurações para Android

Função invokeLocalNotification: Esta é a função que vai invocar uma notificação local, para quando app receber uma notificação e o app estar aberto, fazendo com quem isso o usuário possa visualizar a notificação dentro do aplicativo.

Agora, para que tudo isso realmente funcione, podemos fazer a chamada do nosso setup na SplashScreen, a seguinte função:

void notificationsSetup() {
    NotificationService().setup().then(
      (value) {
        FirebaseMessaging.instance.getInitialMessage().then(
          (message) {
            // FAZ ALGO SE O APP FOI ABERTO ATRAVÉS DA NOTIFICAÇÃO
          },
        );

        FirebaseMessaging.onMessage.listen((RemoteMessage message) {
          // EM QUALQUER MOMENTO QUE CHEGAR NOTIFICAÇÃO E O APP JÁ ESTIVER ABERTO, VAI INVOCAR A NOTIFICAÇÃO LOCAL
          NotificationService().invokeLocalNotification(message);
        });

        FirebaseMessaging.onMessageOpenedApp.listen(
          (RemoteMessage message) {
            // FAZ ALGO SE O APP ESTAVA APENAS "MINIMIZADO" E FOI ABERTO NOVAMENTE
          },
        );
      },
    );
  }

E ai, basta chamar essa função no initState ou didChangeDependencies da tela.

As RemoteMessage podem ser acessadas da seguinte maneira, por exemplo:

message?.data['userId']

Last updated