“Craving a pizza? 🍕 💛 Order now and get $5 off !!”
“Hurry up!! You get a 50% discount on a purchase of a minimum Rs.1000/- 🎉 .”
We become more excited on seeing our screen blinking with alerts like the above.
Ever think about how it reaches your mobile? Push notification is behind the scenes.
When we heard the word push notification for the first time, we must have a thought about how can our mobile be recognized by someone so that they can notify us.
In this blog, we will explore how push notifications are sent using Golang and Firebase.
The device token is the main contestant, responsible for pushing notifications. It’s not a fancy word, it’s simply an id that is unique for each device. When we install any application, our device’s unique token is being stored on their server, using which they can notify us.
Firebase is the tool, used for pushing notifications to apps/mobiles/tablets.
It provides a setting to configure the cloud messaging (FCM) service, which is used for push notifications.
Note: The Firebase config files used at the app side (google_services.json file for Android and GoogleService-Info.plist for iOS) and service_account key must be created for the same project from the Firebase console.
In this blog, we will explore how push notifications are sent using Golang and Firebase.
Here, I’m assuming that you’re familiar with Firebase and configured your project in the Firebase console. If not done already, do it as instructed.
Let’s jump to implementation.
Required packages:
It’s always better to use sensitive stuff in an encrypted format. To serve that purpose I’ve stored the service account key in format base64 encoded as an environment variable.
The sample service account key,
{
"type": "service_account",
"project_id": "fir-realtime-db-demo-xxxxx",
"private_key_id": "9b40ce1e420b06c04b4c8e543bebbd43cd731a22",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIxxxxxxxxxxxxxxw0BAQEFAASCBKgwggSkAgEAAoIBAQDllkqdmGaEonsN\nSsACNopfNG92Ak548KEqDPzw+xxxxxxxxyRMj97Zzz50dY2cUXHmvCwFQhq3KRh7\n9VAFeNflKSmlhw5+ch8eiI1hfqiIpS6Vl+TwVcOSY7SJZaWP9WjCo1inKL6Ur829\nTrKw/54i7TAocaund54ZEFnlhbk0UTSdRwtfzUny5A35EvPXlJazjvkhB5VuB/+F\nxxxxx/ffFcbeqMBwi1Vb9hi1zT2BXV22NUmBxZyp6VQwVfl34XTEZBAutqnVinqz\nuCtkxo+RiZY5yG4csOIkVqsFJ7NYnZE6iwYc1cFtp5IKmP7TZEchyje4crtJUZTf\nC3jyAbrnAgMBAAECggEAXxDBaspNQQSKkXFvWjs9RrjOon3IApoZEfF410rPozAp\nXcbAZBd6vpPrF4wJjD3JPTKTw8WgjFEu+z0T2oA0XYaS4SCwZrlYm2sNp94raRGE\n3ZqcyMuqhLZWbkIxsQ98RoQe1HCxoZ2+QnIQ2euujmXKeCTBYEHOrDAyGTErBDcH\nC98ikFKq/pd6B8ZJ9PbCYIth8KgxQBk+TsY2zEMZN0zM+7fDuTEr914OstT6t6Bb\nAle5aXTYxZNHsTY2mR/4Zo88k4JazEZzQ26BHmi5vdcez6uJuqwoRru0jWAoneTi\nrsUKhajwuKK2nwn+t5m4PABy4hU2VlrJhwPr0o0diQKBgQD42EIP9f9d1JC4OJ3b\nJsQdytTEzcKziF12VAj4rPjGbnWMoIc/6UHO3DNSJyrdZUjakZnaXBnJZkljXsE4\nhJck2s5U80elXH2eWw4qNzLuOxeHlNrZs6HzTzoG0ZGEC2ALvGy5USUsO+a3idsO\nEnklJTEwFdBtqx4MEXPsiyQptQKBgQDsMEcnn9QZLi3SMC+mEeOQDmq7Jm4KygL2\neHVDrq4P4X1Pn7IYqi7iJDxWKBzgCutxFwQOJiZdoedhAg1HhIZckT4VFvkwUHlS\nxu0l21OTFmu/2OUANNDoS8cJwOx+NDe23xbOk6PrVjD4OJtSRc5CDd+reSm1lwVq\nIHizueHDqwKBgD7RWNvunahyIJZgtHi+MIPU0CFeT+hCZFWaoSklgSeWetYlL/9S\nQuqVa98xRADfsKR8XPpihZ/x0lTjdqNt1TnYgn2vbEayMoPnOIwvowvAnw/648RR\nNHDXby6JeNJ8jKJpzoh5k4i3Fmb+xe2nfC2EVgZte1A0AkHJphnwhhCBAoGBAIgl\n5D5xIYBKYFtzL2RZl4Xo6ZlsM67AeCi/k0kqnmfFIckOU0logJIXNTis8sgrQ0Dz\ndYD6eM8sjwYaerEpMZKWnuTlU0uIeAdBaF6UKX72Q7JZQth1mZ7uX5O9xBWT4DHo\nM2ttK+ZyztOnPdGVL6pf+PkNZP+qSJK+mRVxJzT1AoGBANqiyWyH/D26pi1VvoMR\n1DyCWgJIa+Lm0CwR/CE0a1ATdSw1H96WvjEd5oHxlGER7Y9j0nfmvPabWFyNxKbu\nP8ly2aiFffAPKI2e2ZmXXrpcesj0IS5Uk5Mk/1hVwOtNLxGN/ayvk0DqwoIbvFEM\n2EzEYqr/xxxxxxxxxxxxxxxx\n-----END PRIVATE KEY-----\n",
"client_email": "firebase-adminsdk-2zjoi@fir-realtime-db-demo-xxxxx.iam.gserviceaccount.com",
"client_id": "105636361475399593303",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-2zjoi%40fir-realtime-db-demo-fc492.iam.gserviceaccount.com"
}
However, you also can use it in raw format, if security is not concerned.
Here, FIREBASE_AUTH_KEY contains a base64 encoded service account key.
First, let’s decode the service account key.
func getDecodedFireBaseKey() ([]byte, error) {
fireBaseAuthKey := os.Getenv("FIREBASE_AUTH_KEY")
decodedKey, err := base64.StdEncoding.DecodeString(fireBaseAuthKey)
if err != nil {
return nil, err
}
return decodedKey, nil
}
The above method will return the decoded service account key that will be used in the next step.
Retrieve the decoded key and Initialize the Firebase app, using the below code.
decodedKey, err := getDecodedFireBaseKey()
if err != nil {
return err
}
opts := []option.ClientOption{option.WithCredentialsJSON(decodedKey)}
// Initialize firebase app
app, err := firebase.NewApp(context.Background(), nil, opts...)
if err != nil {
log.Debug("Error in initializing firebase app: %s", err)
return err
}
Create fcmClient for messaging(pushing notifications).
fcmClient, err := app.Messaging(context.Background())
if err != nil {
return err
}
Finally, let’s write a code to send a notification.
response, err := fcmClient.Send(context.Background(), &messaging.Message{
Notification: &messaging.Notification{
Title: "Congratulations!!",
Body: "You have just implement push notification",
},
Token: "sample-device-token", // it's a single device token
})
if err != nil {
return err
}
The above code will send a push notification to a single device.
Consider a scenario if you want to notify multiple devices. It will be almost the same as we send a push notification to a single device, just need to replace fcmClient’s Send() method with SendMulticast().
response, err := fcmClient.SendMulticast(context.Background(), &messaging.MulticastMessage{
Notification: &messaging.Notification{
Title: "Congratulations!!",
Body: "You have just implemented push notification",
},
Tokens: deviceTokens, // it's an array of device tokens
})
if err != nil {
return err
}
log.Debug("Response success count : ", response.SuccessCount)
log.Debug("Response failure count : ", response.FailureCount)
Yay !! You have implemented push notifications in your Golang project 🎊.
The response variable will contain the success count and failure count of sent notifications.
Find the full code at FCM with Golang. Invoke SendPushNotification() and boom !! Check a notification received in the application.
Meanwhile, you can also check to debug logs, as it has SuccessCount and failureCount. It will help to verify that notifications are pushed to how many tokens. In case of finding failureCount > 0, you must verify whether you’re giving a valid device token or not.
Keep notifying !!