Search code examples
flutterfirebase-cloud-messaging

Migrate from legacy FCM APIs to HTTP v1 with Flutter & Dart (Depreciated code) solution


I have been reading the google documentation on how to get the Bearer access token but I wasn't able to get it for weeks now but I finally did. The part of replacing the server Key with an access Token is not as clear within the documentation... GitHubLink

Hopefully thiss will save you some time as well.

ensure that you have all these installed firebase_messaging,
firebase_core, http googleapis_auth

ALso, download the service account file from cloud firestore...

  1. Navigate to your project on cloud firebase
  2. Select the gear icon (Project settings)
  3. Select the service account tab
  4. Generete the file 5.locate the file on you local pc or machine
  5. finally, use those variables and fill the "FILL_UP" placeholder on getAccessToken method

  static Future<void> sendNotificationToTopicAllToSee(String title,
      String description, String topicTOSubscribe) async {
    try {

      String? accessToken = await generateFCMAccessToken();
      
      var notification = {
        "message": {
          "notification": {
            'title': title,
            'body': description,
          },
          'data': <String, String>{
            'click_action': 'FLUTTER_NOTIFICATION_CLICK',
            'id': '1',
            'status': 'done',
          },
          "topic": topicTOSubscribe,
        }
      };

      if(token != null){
        // Send the notification
      final response = await http.post(
        Uri.parse(
            'https://fcm.googleapis.com/v1/projects/REPLACE_WITH_PROJECT_NAME/messages:send'),
        headers: <String, String>{
          'Content-Type': 'application/json',
          'Authorization': 'Bearer $accessToken',
        },
        body: jsonEncode(notification),
      );
      }else{
        print("Token is empty/null);
      }

      if (response.statusCode == 200) {
        print('Notification sent successfully');
      } else {
        print('Failed to send notification: ${response.body}');
      }
    } catch (e) {
      print('Error sending notification: $e');
    }
  }



 

Solution

  • Get the bearer access token

      static Future<String> generateFCMAccessToken() async {
        try {
          /* get these details from the file you downloaded(generated)
              from firebase console
          */
          String type = "FILL_UP";
          String project_id = "FILL_UP";
          String private_key_id = "FILL_UP";
          String private_key = "FILL_UP";
          String client_email = "FILL_UP";
          String client_id = "FILL_UP";
          String auth_uri = "FILL_UP";
          String token_uri = "FILL_UP";
          String auth_provider_x509_cert_url = "FILL_UP";
          String client_x509_cert_url = "FILL_UP";
          String universe_domain = "FILL_UP";
    
          final credentials = ServiceAccountCredentials.fromJson({
            "type": type,
            "project_id": project_id,
            "private_key_id": private_key_id,
            "client_email": client_email,
            "private_key": private_key,
            "client_id": client_id,
            "auth_uri": auth_uri,
            "token_uri": token_uri,
            "auth_provider_x509_cert_url": auth_provider_x509_cert_url,
            "client_x509_cert_url": client_x509_cert_url,
            "universe_domain": universe_domain
          });
    
          List<String> scopes = [
            "https://www.googleapis.com/auth/firebase.messaging"
          ];
    
          final client = await obtainAccessCredentialsViaServiceAccount(
              credentials, scopes, http.Client());
          final accessToken = client;
          Timer.periodic(const Duration(minutes: 59), (timer) {
            accessToken.refreshToken;
          });
          return accessToken.accessToken.data;
        } catch (e) {
          Reuse.logger.i("THis is the error: $e");
        }
        return "";
      }
    

    The above implementation works correctly when I test and run it. Please feel free to better the code if you have a better way ofdoing this.