(Flutter) Send POST request for FCM notifications
Tags: flutter, firebase, fcm, postman
Published: 2022-10-25 14:59:05

My ultimate goal for my project was to send push notifications for users though the client app. Ill be showing you my learning processes from the start all to how I learned to solve this problem.

First lets lay out the problem: my mission is to send push notifications to specific users through the client app when a user pushes a button in his screen. 
The framework im using is Flutter and Firebase in the backend. Firebase is set up and Firebase cloud messaging can be set up easily from the [following guide by Harsivo Edu](https://www.youtube.com/watch?v=m2zuJw5c7bw&t) 
I'm referencing an [introduction video to FCM from Fireship](https://www.youtube.com/watch?v=2TSm2YGBT1s&t) if you are not familiar with the feature.

After FCM is set up make sure to enable Cloud Messaging API (Legacy) in the project settings -> cloud massaging.

Once that is set up well we can test if everything works in Postman
go to the website and make a new POST request, then go to the headers section and set everything up like the picture bellow

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ar79x762495pxujflkvw.png)
In the POST request enter the following "https://fcm.googleapis.com/fcm/send" which is the REST API HTTP call to FCM.

In the "Authorization" VALUE enter the server key from under the Cloud Messaging API (Legacy) as shown in the red rectangle:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d23md3yb1ydosfamkte8.png)

Now lets click the body section and write our request in JSON format:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nfa16h3yhq6sp2t3rojn.png)

inside the "to" we want to reference the device id we'll be sending the notification to.
we can find the device token id with the code bellow:
```dart
  Future<String?> saveDeviceToken() async {
    String? deviceToken = '@';

    try {
      deviceToken = await FirebaseMessaging.instance.getToken();
    } catch (e) {
      print('could not get token');
      print(e.toString());
    }
    if (deviceToken != null) {
      print("--------------Device Token--------------" + deviceToken);
    }
    return deviceToken;
  }
```
then call the `saveDeviceToken()` in then initState, or through a button or any other way.
hot restart the app then well get the device token id inside the debug console in VSCode. that token is what we paste the "to" parameter. which will reference this device only.

finally we click Send and wait, after couple of seconds we sould see the following: 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rldivnjlhelnv8ajzla7.png)
`"failure": 0` means the request worked and there werent any issues. if an emulator is running you should get a notification too
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mejlw37hyyc1jvd4r2ba.png)
if id didn't work for you then make sure you set up FCM correctly.

OK! so we've done all that and now we want to send it though the client (through the app).
The following stackoverflow posts helped me to understand how to do it:
[Post 1](https://stackoverflow.com/questions/71299214/send-notification-to-specific-user-firebase-in-flutter#:~:text=This%20can%20simply%20be%20done,token%20to%20send%20it%20to)
[Post 2](https://stackoverflow.com/questions/71299214/send-notification-to-specific-user-firebase-in-flutter)
[Post 3](https://stackoverflow.com/questions/52226762/flutter-send-notificiation-from-client-app-with-curl)

for my purposes i found this answer in post 3 by user Stephan Schlecht, so i made a new class in a new widget i called postNotifications.dart and copied the code bellow
```dart
import 'dart:async';
import 'dart:convert' show Encoding, json;
import 'package:http/http.dart' as http;

class PostCall {
  final postUrl = 'https://fcm.googleapis.com/fcm/send';

  final data = {
    "notification": {"body": "this is a body", "title": "this is a title"},
    "priority": "high",
    "data": {
      "click_action": "FLUTTER_NOTIFICATION_CLICK",
      "id": "1",
      "status": "done"
    },
    "to": "<DEVICE TOKEN ID>"
  };

  Future<bool> makeCall() async {
    final headers = {
      'content-type': 'application/json',
      'Authorization': 'key=<FCM SERVER KEY>'
    };

    final response = await http.post(Uri.parse(postUrl),
        body: json.encode(data),
        encoding: Encoding.getByName('utf-8'),
        headers: headers);

    if (response.statusCode == 200) {
      // on success do sth
      return true;
    } else {
      // on failure do sth
      return false;
    }
  }
}
```
Enter the <FCM SERVER KEY> and the <DEVICE TOKEN ID>. then i called the function `makeCall()` with a button and it all worked out!

now this is the end of the guide for now. next my objective is to sent the notification to other devices that fit a certain criteria.
the [FCM documentetion](https://firebase.google.com/docs/cloud-messaging/http-server-ref) has all the parameter you can enter inside the JSON and their usage.

Thank you for following to the end of the guide.

-T