# Firebase cloud messaging and python 3

It is one thing to acquire users and another to retain them. One way of maintaining users is to keep them engaged is via notifications and Firebase Cloud Messaging can help in delivering these notifications.
The objective of this tutorial is to show you how to send messages to your users via two methods, one using registration tokens and the second using topics; which is a less popular method that I think people don't know that much.
Code examples shall be done in python but the concepts can be applied to other languages. ( just a disclaimer)


## Let's get started
For this tutorial, I shall assume you have python installed on your computer and `pip`, python package manager.

Pre-steps:
- Head over to [Firebase console](https://console.firebase.google.com/) and create a project
- Create a service account; visit this [link](https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts/create?supportedpurview=project). Remember you can select a project as demonstrated below
![image (8).png](https://cdn.hashnode.com/res/hashnode/image/upload/v1641651408213/5YDtyOdpE.png)

- Create or upload keys; once you have created a service account, you shall be redirected to the page with all service accounts available, Tap on the key that has the name **firebase-adminsdk**
![image (9).png](https://cdn.hashnode.com/res/hashnode/image/upload/v1641651800135/-VWv83yH8o.png)

- Download a **credential json** file; navigate to the **keys** tab and tap the **Add Key** button, choose **JSON** key type, and automatically it should download a credential json file

## let's write some code
I am intending to write a utils class that you can always reuse while maintaining a cleaner code type of style.
Firebase has developed a PyPI library that makes it easy to use firebase service with python so run this:

```bash
pip install firebase-admin
```

Create a file named `fcm_utils.py` and paste the following 
```
from typing import Any
from firebase_admin import messaging, credentials
import firebase_admin


class FcmUtils:
    def __init__(self):
        creds = credentials.Certificate(
            'utils/nilipie-9d6b9-0dbc5b6385b9.json')
        default_app = firebase_admin.initialize_app(creds)

    # send_to_token
    # Send a message to a specific token
    # registration_token: The token to send the message to
    # data: The data to send to the token
    # {
    #   'score': '850',
    #   'time': '2:45',
    # },
    # example
    def send_to_token(self, registration_token, title, body, data=None) -> Any:
        message = messaging.Message(
            notification=messaging.Notification(
                title=title,
                body=body,
            ),
            data=data,
            token=registration_token
        )
        response = messaging.send(message)
        print(response)
        return response

    # send_to_token_multicast
    # Send a message to a specific tokens
    # registration_tokens: The tokens to send the message to
    # data: The data to send to the tokens
    def send_to_token_multicast(self, registration_tokens, title, body, data=None) -> Any:
        # registration_tokens has to be a list
        assert isinstance(registration_tokens, list)

        message = messaging.MulticastMessage(
            notification=messaging.Notification(
                title=title,
                body=body,
            ),
            data=data,
            token=registration_tokens
        )
        response = messaging.send_multicast(message)
        print(response)
        # See the BatchResponse reference documentation
        # for the contents of response.
        return response

    # send_to_topic
    # Send a message to a topic
    # topic: The topic to send the message to
    # data: The data to send to the topic
    # {
    #   'score': '850',
    #   'time': '2:45',
    # },
    # example
    def send_to_topic(self, topic, title, body, data=None) -> Any:
        message = messaging.Message(
            notification=messaging.Notification(
                title=title,
                body=body,
            ),
            data=data,
            topic=topic
        )
        response = messaging.send(message)
        print(response)
        # Response is a message ID string.
        return response

```

Note: Don't forget to replace this line `utils/nilipie-9d6b9-0dbc5b6385b9.json` with the path to your JSON file.

The `FcmUtils` class exposes three methods:
1. `send_to_token` 
Sends a message to a specific token

2. `send_to_token_multicast`
Practically the same as sending to a token instead you can send to one or many tokens in one request, hence it accepts a list of tokens (strings)

3. `send_to_topic`
The last method sends a message to a specific topic, i.e clients need to be subscribed to this topic

Now the util class can be used as follows:

```python
from fcm_utils import FcmUtils

def main():
    messaging = FcmUtils()
    messaging.send_to_topic("topics-all", "title", "body from topic")

if __name__ == "__main__":
    main()
```

Results:

![Screenshot_1641557702.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1641557721026/Y0Qz8cUzY.png)

## Conclusion
That was fun and easy, hope you learned something, and please comment if you have any queries... just as a by the way the mobile screenshot is a **Flutter** app running on an Android emulator.
