Code With Bisky

Ultimate Flutter & Firebase Cloud Messaging Integration Guide | Step-by-Step Tutorial Episode [21]

Key Topics covered:

  • Use flutterfire client
  • Show Push Notifications when application is in background
  • Configure Firebase in your flutter application
  • Send push notification

Description:

In this tutorial, you will learn how to implement Firebase Cloud Messaging (FCM) in your Flutter app! 🔥 In this step-by-step tutorial, you'll discover the easiest way to send and receive push notifications using Flutter and Firebase. 📢 Stay up-to-date with real-time updates and engage your users like never before! 💬 Don't miss out on this comprehensive guide to integrating FCM into your Flutter projects. 📚 Boost user engagement, enhance your app's functionality, and keep your users informed with our practical examples and easy-to-follow code. 🎯 Master the art of push notifications with Flutter and Firebase now!

Add the following dependencies in your pubspec.yaml.


dependencies:
  .........
  firebase_core: ^2.13.1
  cloud_firestore: ^4.8.2
  firebase_messaging: ^14.6.2
  awesome_notifications: ^0.7.4+1

        
        

Firebase Setup

  • Create a new firebase project here
  • Create and configure android and ios apps
  • Make sure you installed firebase client on your computer. check it here
  • Login with firebase by running this command firebase login
  • Go to your root folder of your project
  • run below code
  • 1. dart pub global activate flutterfire_cli
  • 2. export PATH="$PATH":"$HOME/.pub-cache/bin"
  • 3. flutterfire configure
  • You are done

Code Snippet(strings.dart) modification:

  • lib/constant/strings.dart

Follow the video and see how you can generate a server key


 static var serverKey ='AAAAnOjOofM:APA91bERxS6wmtdiipPgkRlvA9Z8FlcFqjBa5oKimNv7u_A63itn5aOgKgLx9vLuRSn9pJWxGa5HyWVI19EdhOco0XaQcHmFZ8IEZZQCr-Vkhep-vO-XlJuSuQsAQvYVhCTyO2sW09gQ';
        
        

Code Snippet(FirebaseProvider.dart):

  • lib/core/providers/FirebaseProvider.dart

Create FirebaseProvider and add a method to send push notification to another user


import 'dart:convert';

import 'package:chat_with_bisky/constant/strings.dart';
import 'package:http/http.dart' as http;

sendPayload(String token, Map<String, dynamic> data) async{

  http.Response response = await http.post(Uri.parse("https://fcm.googleapis.com/fcm/send"),
  headers: <String,String>{
    'Content-Type':'application/json',
    'Authorization':'key=${Strings.serverKey}'
  },body:  jsonEncode( {
      'data':data,
      'to':token
      }),
  );
  print('Code ${response.statusCode}');
  print('Body ${response.body}');
}
 
        

Code Snippet(UserRepositoryProvider.dart):

  • lib/core/providers/UserRepositoryProvider.dart

Create a method to update user. We want to update user token being used for push notifications


  Future<UserAppwrite?> updateUser(UserAppwrite userAppwrite) async {
    try {
      Document document = await _db.updateDocument(
          databaseId: Strings.databaseId,
          collectionId: Strings.collectionUsersId,
          documentId: userAppwrite.userId ?? "",
      data: userAppwrite.toJson());

      return UserAppwrite.fromJson(document.data);
    } on AppwriteException catch (e) {
      print('ERROR updateFirebaseToken $e');
    } catch (e) {
      print('ERROR updateFirebaseToken $e');
    }
    return null;
  }
 

Code Snippet(main.dart):

  • lib/main.dart

We need to configure AwesomeNotifications and initialize Firebase in main() method


if (Platform.isIOS) {
    await Firebase.initializeApp(
        options: DefaultFirebaseOptions.currentPlatform);
  } else {
    await Firebase.initializeApp();
  }

  await AwesomeNotifications().initialize(
    null,
    [
      NotificationChannel(
          channelGroupKey: 'category_tests',
          channelKey: 'CodeWithBiskyChannelId',
          channelName: 'Calls Channel',
          channelDescription: 'Channel with call ringtone',
          defaultColor: const Color(0xFF9D50DD),
          importance: NotificationImportance.Max,
          ledColor: Colors.white,
          channelShowBadge: true,
          locked: true,
          defaultRingtoneType: DefaultRingtoneType.Ringtone),
    ],
  );

  FirebaseMessaging.onBackgroundMessage(myBackgroundMessageHandler);
 

We need to create myBackgroundMessageHandler method to handle push notifications


Future<void> myBackgroundMessageHandler(RemoteMessage message) async {
  final map = message.toMap();
  print('background message ${map.toString()}');
  final data = map['data'];
  if (data.containsKey('messageType')) {
    final messageType = data['messageType'];
    if (messageType == AttachmentType.text) {
      bool isAllowed = await AwesomeNotifications().isNotificationAllowed();
      if (!isAllowed) return;
      await AwesomeNotifications().createNotification(
          content: NotificationContent(
        id: 888,
        channelKey: 'CodeWithBiskyChannelId',
        title: 'Message: ${data['fromName']}',
        body: "${data['message']}",
      ));
    }
  }
 

Code Snippet(UserAppwrite.dart):

  • lib/model/UserAppwrite.dart

Add property firebaseToken. We want to save it into the database


String? firebaseToken;
 

Don't forget to run the following command in your terminal to generate firebaseToken flutter packages pub run build_runner build

Code Snippet(DashboardPage.dart):

  • lib/pages/dashboard/DashboardPage.dart

Create a method to generate firebase token and save it to the database


@override
  void initState() {
    super.initState();
    createFirebaseToken();
  }

  createFirebaseToken(){
    FirebaseMessaging.instance.getToken().then((value) async {
      String userId = await LocalStorageService.getString(LocalStorageService.userId) ?? "";
        final myUser =  await ref.read(userRepositoryProvider).getUser(userId);
        if(myUser != null && myUser.firebaseToken != value){
          myUser.firebaseToken = value;
          await ref.read(userRepositoryProvider).updateUser(myUser);
    });
  }

 

Code Snippet(MessageViewModel.dart):

  • lib/pages/dashboard/chat/MessageViewModel.dart

Create a method to create and send push notification after we save a message


 sendPushNotificationMessage(MessageAppwrite messageAppwrite) async {
    final friendUser = await ref
        .read(userRepositoryProvider)
        .getUser(messageAppwrite.receiverUserId ?? "");
    final myUser = await ref
        .read(userRepositoryProvider)
        .getUser(messageAppwrite.senderUserId ?? "");

    if (friendUser != null && myUser != null) {
      final body = {
        'fromName': myUser.name ?? "",
        'messageType': messageAppwrite.type ?? "",
        'message': messageAppwrite.message ?? "",
        'fromUserId': myUser.userId ?? "",
      };

      if (friendUser.firebaseToken != null) {
        sendPayload(friendUser.firebaseToken!, body);
      }
    }
  }

 

Conclusion:

We managed to implement push notification after sending a message to a friend. You are now able to create a firebase project and apps (ios and android). We managed to utilize flutterfire cli to generate google-services files easily. We are able to create firebase token and server key. Don't forget to share and join our Discord Channel. May you please subscribe to our YouTube Channel.