Vue.js VueFire FCM Cloud Functions
▌Introduction
In the previous article, [Vue]
Shopcart example with Firebase Cloud Messaging and Functions (1), we had
learned how to send a FCM message to client by Google FCM Web api.
The architecture should be like
this.
▋Related articles
▌Environment
▋Vue.js 2.5.11
▋Vue CLI 3.2.1
▋Firebase Javascript SDK 5.5.8
▋VueFire 1.4.5
▌Implement
▋Install
Requirements:
1. Node.js
2. NPM
3. Firebase CLI
To initialize the implement environment on your
Vue.js (or other) project, use the commands:
$ firebase login
$ firebase init functions
During
initialing Firebase Cloud Functions, choose your target Firebase project,
implement language (JS or TypeScript) and install the dependent npm packages.
PS.
I will use JS in this tutorial.
The Firebase CLI will create
the directories and files as below.
index.js is the main source file for your Cloud Functions code.
The packages we need are as
following, make sure they are installed to your project.
"dependencies": {
"cors": "^2.8.5",
"firebase-admin": "~6.0.0",
"firebase-functions": "^2.1.0"
}
▋Implement Cloud Functions
We will
create a Cloud Function with Firebase HTTPS API: functions.https
and its listener event: onRequest()
to replace sending request to FCM Web api for pushing the discount notification
to clients.
From
document: Call
functions via HTTP requests
Use
functions.https to create a function that handles HTTP events. The
event handler for an HTTP function listens for the onRequest() event, which supports routers and apps managed by
the Express web
framework. |
The type
of onRequest()’s
parameter is function(non-null express.Request,
non-null express.Response)
We can
get the useful properties/methods of express.Request as
following,
Prop
|
Description
|
Value for example
|
request.method
|
Http Method kind
|
"POST"
|
request.get("<header>")
|
Get header’s value
|
"bearer fdsdfpokendofdg"
|
request.query.<url param>
|
Get url param’s value
|
Url: https://xxx/?age=30
request.query.age will be 30 |
request.body.<prop>
|
request.body contains
key-value pairs of data submitted in the request body. So we can get the
value by prop name.
|
Assume body is
{"name":"JB"} request.body.name will be "JB" |
request.rawBody
|
The raw (unparsed) bytes of the
request
|
""
|
Notice in
onRequest(),
we can use one of these APIs to send FCM messages:
2. Admim
FCM API (Supports Node, Java, Python and Go)
▋Legacy FCM server API
const functions = require("firebase-functions")
const cors = require('cors')({ origin: true });
const admin = require("firebase-admin")
admin.initializeApp();
exports.sendDiscountMsg =
functions.https.onRequest((request, response) => {
cors(request,
response, () => {
const userToken =
request.get("token");
const userName =
request.get("user-name")
response.end();
/* Legacy
FCM server API :
https://firebase.google.com/docs/cloud-messaging/admin/legacy-fcm */
//
Notification details.
let payload = {
notification: {
title: "Advertisements",
body: `Hi ${userName}, we have
special discount for you, visit here for more details!`,
click_action: "https://xxxxx.firebaseapp.com",
icon: "dist/firebase-logo.png"
}
};
// Send
notifications to device
return
admin.messaging().sendToDevice(userToken, payload);
})
▋Admin FCM API (Node.js)
const functions = require("firebase-functions")
const cors = require('cors')({ origin: true });
const admin = require("firebase-admin")
admin.initializeApp();
exports.sendDiscountMsg =
functions.https.onRequest((request, response) => {
cors(request,
response, () => {
const userToken =
request.get("token");
const userName =
request.get("user-name")
response.end();
/* Admin
FCM API (Node.js): https://firebase.google.com/docs/cloud-messaging/admin/send-messages
*/
let message = {
webpush: {
notification: {
title: "Advertisements",
body: `Hi ${userName}, we have
special discount for you, visit here for more details!`,
click_action: "https://xxxxxx.firebaseapp.com",
icon: "dist/firebase-logo.png"
}
},
token:
userToken
};
return
admin.messaging().send(message)
.then((response) => {
// Response
is a message ID string.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
});
})
As you
can see, the request should contains 2 custom header:
Header
|
Description
|
Token
|
User’s registration token
|
user-name
|
The display name of user
|
▋Deploy the Cloud Functions
Its easy
to deploy the Cloud Functions by Firebase CLI:
$ firebase deploy --only functions
Back to
Firebase Console, we will see the Functions just deployed.
▋Example: Send the discount message when user go to shopping page
Now we have the Cloud Functions and we are Serverless :),
so we will make the client requests the Function to trigger sending FCM message
to himself.
(Ok, I know it’s a weird scenario and please don’t mind)
Lets modify our Vue.js app, add the pushDiscountMsg()
to request the Cloud Function with user’s name and token as following,
new Vue({
el: '#app',
methods: {
async setFbMessaging()
{
let msgService
= new messagingService();
//Request
permission
await msgService.requestPermissionAsync();
//Retrieve
token
await msgService.getTokenAsync();
},
pushDiscountMsg(token, user) {
console.log("Start
push msg with token: " + token);
this.axios
.get(
"https://<your
domain>.cloudfunctions.net/sendDiscountMsg",
{
headers: {
token: token,
"user-name": user
}
}
)
.then(result => {
console.log(result);
});
}
},
created() {
var vm
= this;
vm.setFbMessaging().then(token => {
vm.pushDiscountMsg(token, firebaseAuth.currentUser);
});
//Add callback
for receiving FCM
firebaseMessaging.onMessage(function(payload) {
let notification
= payload.notification;
alert(notification.body);
});
}
};
沒有留言:
張貼留言