16
16
'use strict' ;
17
17
18
18
const functions = require ( 'firebase-functions' ) ;
19
- const firebaseAdmin = require ( 'firebase-admin' ) ;
20
- const serviceAccount = require ( './service-account.json' ) ;
21
- firebaseAdmin . initializeApp ( {
22
- credential : firebaseAdmin . credential . cert ( serviceAccount ) ,
23
- databaseURL : `https://${ serviceAccount . project_id } .firebaseio.com`
24
- } ) ;
25
- const rp = require ( 'request-promise-native' ) ;
19
+ const admin = require ( 'firebase-admin' ) ;
20
+ admin . initializeApp ( functions . config ( ) . firebase ) ;
26
21
27
22
/**
28
23
* Triggers when a user gets a new follower and sends a notification.
29
24
*
30
- * Followers add a flag to `followers/{followedUid}/{followerUid}`.
31
- * Users save their device notification tokens to `users/{followedUid}/notificationTokens/{notificationToken}`.
25
+ * Followers add a flag to `/ followers/{followedUid}/{followerUid}`.
26
+ * Users save their device notification tokens to `/ users/{followedUid}/notificationTokens/{notificationToken}`.
32
27
*/
33
- exports . sendFollowerNotification = functions . database ( ) . path ( ' followers/{followedUid}/{followerUid}') . onWrite ( event => {
28
+ exports . sendFollowerNotification = functions . database . ref ( '/ followers/{followedUid}/{followerUid}') . onWrite ( event => {
34
29
const followerUid = event . params . followerUid ;
35
30
const followedUid = event . params . followedUid ;
36
31
// If un-follow we exit the function.
@@ -40,10 +35,10 @@ exports.sendFollowerNotification = functions.database().path('followers/{followe
40
35
console . log ( 'We have a new follower UID:' , followerUid , 'for user:' , followerUid ) ;
41
36
42
37
// Get the list of device notification tokens.
43
- const getNotificationTokensPromise = firebaseAdmin . database ( ) . ref ( `users/${ followedUid } /notificationTokens` ) . once ( 'value' ) ;
38
+ const getNotificationTokensPromise = admin . database ( ) . ref ( `/ users/${ followedUid } /notificationTokens` ) . once ( 'value' ) ;
44
39
45
40
// Get the follower profile.
46
- const getFollowerProfilePromise = firebaseAdmin . auth ( ) . getUser ( followerUid ) ;
41
+ const getFollowerProfilePromise = admin . auth ( ) . getUser ( followerUid ) ;
47
42
48
43
return Promise . all ( [ getNotificationTokensPromise , getFollowerProfilePromise ] ) . then ( results => {
49
44
const tokensSnapshot = results [ 0 ] ;
@@ -55,56 +50,33 @@ exports.sendFollowerNotification = functions.database().path('followers/{followe
55
50
}
56
51
console . log ( 'There are' , tokensSnapshot . numChildren ( ) , 'tokens to send notifications to.' ) ;
57
52
console . log ( 'Fetched follower profile' , follower ) ;
58
- const displayName = follower . displayName ;
59
- const profilePic = follower . photoURL ;
60
-
61
- // Sends notifications to all tokens.
62
- const notificationPromises = [ ] ;
63
- tokensSnapshot . forEach ( tokenSnapshot => {
64
- const token = tokenSnapshot . key ;
65
- const notificationPromise = sendNotification ( displayName , token , followedUid , profilePic ) ;
66
- notificationPromises . push ( notificationPromise ) ;
67
- } ) ;
68
-
69
- return Promise . all ( notificationPromises ) . then ( ( ) => {
70
- console . log ( 'Marked notification as sent.' ) ;
71
- console . log ( 'Finished sending notifications.' ) ;
72
- } ) ;
73
- } ) ;
74
- } ) ;
75
53
76
- /**
77
- * Sends a "New follower" notification to the given `token`.
78
- * Removes/cleans up the token from the database if they are not registered anymore.
79
- */
80
- function sendNotification ( displayName , token , followedUid , profilePic ) {
81
- // Prepare the REST request to the Firebase Cloud Messaging API.
82
- var options = {
83
- method : 'POST' ,
84
- uri : 'https://fcm.googleapis.com/fcm/send' ,
85
- headers : {
86
- Authorization : `key=${ functions . env . firebase . apiKey } `
87
- } ,
88
- body : {
54
+ // Notification details.
55
+ const payload = {
89
56
notification : {
90
57
title : 'You have a new follower!' ,
91
- body : `${ displayName } is now following you.` ,
92
- icon : profilePic || 'https://ssl.gstatic.com/images/icons/material/product/1x/avatar_square_blue_120dp.png'
93
- } ,
94
- to : token
95
- } ,
96
- json : true
97
- } ;
58
+ body : `${ follower . displayName } is now following you.` ,
59
+ icon : follower . photoURL
60
+ }
61
+ } ;
98
62
99
- // Send the REST request to the Firebase Cloud Messaging API.
100
- return rp ( options ) . then ( resp => {
101
- console . log ( 'Sent a notification.' , resp . success ? 'Success' : 'Failure' ) ;
63
+ // Listing all tokens.
64
+ const tokens = Object . keys ( tokensSnapshot . val ( ) ) ;
102
65
103
- // Cleanup the tokens who are not registered anymore.
104
- if ( resp . failure && resp . results [ 0 ] . error === 'NotRegistered' ) {
105
- return firebaseAdmin . database ( ) . ref ( `users/${ followedUid } /notificationTokens/${ token } ` ) . remove ( ) . then ( ( ) => {
106
- console . log ( 'Removed unregistered token.' ) ;
66
+ // Send notifications to all tokens.
67
+ return admin . messaging ( ) . sendToDevice ( tokens , payload ) . then ( response => {
68
+ // For each message check if there was an error.
69
+ response . results . forEach ( ( result , index ) => {
70
+ const error = result . error ;
71
+ if ( error ) {
72
+ console . error ( 'Failure sending notification to' , tokens [ index ] , error ) ;
73
+ // Cleanup the tokens who are not registered anymore.
74
+ if ( error . code === 'messaging/invalid-registration-token' ||
75
+ error . code === 'messaging/registration-token-not-registered' ) {
76
+ return tokensSnapshot . ref . child ( tokens [ index ] ) . remove ( ) ;
77
+ }
78
+ }
107
79
} ) ;
108
- }
80
+ } ) ;
109
81
} ) ;
110
- }
82
+ } ) ;
0 commit comments