Skip to content

Commit 0b5ed2e

Browse files
committed
FCM Web quickstart
Change-Id: I44522e44cf257df89127d1ea3f901a965f5267cc
1 parent ae90d24 commit 0b5ed2e

8 files changed

+427
-0
lines changed

Diff for: README.md

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ Samples available:
2121
- Simple Social Blogging app
2222
- [Storage](storage)
2323
- Upload a file to Firebase Storage and display its URL
24+
- [Messaging](messaging)
25+
- Send notifications
2426

2527
## How to make contributions?
2628
Please read and follow the steps in the [CONTRIBUTING.md](CONTRIBUTING.md)

Diff for: messaging/README.md

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
Firebase Cloud Messaging Quickstart
2+
===================================
3+
4+
The Firebase Cloud Messaging quickstart demonstrates how to request permission
5+
to notify the user and receive FCM messages using the Firebase Cloud Messaging
6+
JavaScript SDK.
7+
8+
Introduction
9+
------------
10+
11+
- [Read more about Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging/)
12+
13+
Getting Started
14+
---------------
15+
16+
- Set up your project on the [Firebase Console](https://console.firebase.google.com).
17+
- Replace the config object defined in `index.html` with the one generated from
18+
the Firebase Console **Overview > Add Firebase to your web app**.
19+
- Run `firebase serve -p 8081` using the [Firebase CLI](https://firebase.google.com/docs/cli/)
20+
tool to launch a local server and open the sample `.html` in a web browser.
21+
- Click REQUEST PERMISSION button to request permission for your app to send
22+
notifications to the browser.
23+
- After the Instance ID token is generated you can use it to send an HTTP request
24+
to FCM that delivers the message to the web application.
25+
### HTTP
26+
```
27+
POST /fcm/send HTTP/1.1
28+
Host: fcm.googleapis.com
29+
Authorization: key=YOUR-SERVER-KEY-HERE
30+
Content-Type: application/json
31+
32+
{
33+
"notification": {
34+
"title": "Portugal vs. Denmark",
35+
"body": "5 to 1",
36+
"icon": "firebase-icon.png",
37+
"click_action": "http://localhost:8081"
38+
},
39+
"to": "YOUR-TOKEN-HERE"
40+
}
41+
```
42+
### cURL
43+
```
44+
curl -X POST -H "Authorization: key=YOUR-SERVER-KEY-HERE" -H "Content-Type: application/json" -d '{
45+
"notification": {
46+
"title": "Portugal vs. Denmark",
47+
"body": "5 to 1",
48+
"icon": "firebase-icon.png",
49+
"click_action": "http://localhost:8081"
50+
},
51+
"to": "YOUR-TOKEN-HERE"
52+
}' "https://fcm.googleapis.com/fcm/send"
53+
```
54+
- When the app has the browser focus , the received message is handled through
55+
the `onMessage` callback in index.html. When the app does not have browser
56+
focus then the `setBackgroundMessageHandler` callback in firebase-messaging-sw.js
57+
is where the received message is handled.
58+
59+
### Browser focus
60+
Your app would be considered as having focus if it is running in the currently
61+
selected browser tab. Otherwise it would be considered not in focus.
62+
63+
Support
64+
-------
65+
66+
https://firebase.google.com/support/
67+
68+
License
69+
-------
70+
71+
© Google, 2016. Licensed under an [Apache-2](../LICENSE) license.

Diff for: messaging/firebase-logo.png

3.46 KB
Loading

Diff for: messaging/firebase-messaging-sw.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
importScripts('https://www.gstatic.com/firebasejs/3.4.0/firebase-app.js');
2+
3+
firebase.initializeApp({});
4+
5+
const messaging = firebase.messaging();
6+
7+
// If you would like to customize notifications that are received in the
8+
// background (Web app is closed or not in browser focus) then you should
9+
// implement this optional method.
10+
// [START background_handler]
11+
messaging.setBackgroundMessageHandler(function(data) {
12+
console.log('[firebase-messaging-sw.js] Received background message ', data);
13+
// Show notification here
14+
const notificationTitle = 'Background Message Title';
15+
const notificationOptions = {
16+
body: 'Background Message body.',
17+
icon: '/firebase-logo.png'
18+
};
19+
20+
return self.registration.showNotification(notificationTitle,
21+
notificationOptions);
22+
});
23+
// [END background_handler]

Diff for: messaging/index.html

+253
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
<!DOCTYPE html>
2+
<!--
3+
Copyright (c) 2016 Google Inc.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<html>
18+
<head>
19+
<meta charset=utf-8/>
20+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
21+
<title>Firebase Cloud Messaging Example</title>
22+
23+
<!-- Material Design Theming -->
24+
<link rel="stylesheet" href="https://code.getmdl.io/1.1.3/material.orange-indigo.min.css">
25+
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
26+
<script defer src="https://code.getmdl.io/1.1.3/material.min.js"></script>
27+
28+
<link rel="stylesheet" href="main.css">
29+
</head>
30+
<body>
31+
<div class="demo-layout mdl-layout mdl-js-layout mdl-layout--fixed-header">
32+
33+
<!-- Header section containing title -->
34+
<header class="mdl-layout__header mdl-color-text--white mdl-color--light-blue-700">
35+
<div class="mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-grid">
36+
<div class="mdl-layout__header-row mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-cell--8-col-desktop">
37+
<h3>Firebase Cloud Messaging</h3>
38+
</div>
39+
</div>
40+
</header>
41+
42+
<main class="mdl-layout__content mdl-color--grey-100">
43+
<div class="mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-grid">
44+
45+
<!-- Container for the Table of content -->
46+
<div class="mdl-card mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-cell--12-col-desktop">
47+
<div class="mdl-card__supporting-text mdl-color-text--grey-600">
48+
<div id="token_div" style="display: none;">
49+
<h4>Token</h4>
50+
<p id="token" style="word-break: break-all;"></p>
51+
<button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"
52+
onclick="deleteToken()">Delete Token</button>
53+
</div>
54+
<div id="permission_div" style="display: none;">
55+
<h4>Needs Permission</h4>
56+
<p id="token"></p>
57+
<button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"
58+
onclick="askPermission()">Request Permission</button>
59+
</div>
60+
<div id="messages"></div>
61+
</div>
62+
</div>
63+
64+
</div>
65+
</main>
66+
</div>
67+
<!-- Firebase -->
68+
<!-- *******************************************************************************
69+
* TODO(DEVELOPER): Paste the initialization snippet by navigating to:
70+
https://console.firebase.google.com
71+
and choosing a project you've created. Then click the red HTML logo at the top
72+
right of the page with the caption "Add Firebase to your web app".
73+
Copy the snippet that appears in place of this comment.
74+
*************************************************************************** -->
75+
<script>
76+
// [START get_messaging_object]
77+
const messaging = firebase.messaging();
78+
// [END get_messaging_object]
79+
const tokenDivId = 'token_div';
80+
const permissionDivId = 'permission_div';
81+
82+
// [START refresh_token]
83+
// Called if InstanceID token is updated. This may occur if the security of
84+
// the previous token had been compromised. Note that you will have to
85+
// re-subscribe the new token to the topics that the previous token was
86+
// subscribed to.
87+
messaging.onTokenRefresh(function() {
88+
messaging.getToken()
89+
.then(function(refreshedToken) {
90+
console.log('Token refreshed.');
91+
setTokenSentToServer(false);
92+
sendTokenToServer(refreshedToken);
93+
resetUI();
94+
});
95+
});
96+
// [END refresh_token]
97+
98+
// [START receive_message]
99+
// Handle messages that are received by this page. This is called when a
100+
// message is received while the app is in the foreground or when the user
101+
// clicks on a the notification resulting from the user clicking on a
102+
// notification message.
103+
messaging.onMessage(function(payload) {
104+
console.log("Message received.");
105+
console.log(payload);
106+
// [START_EXCLUDE]
107+
appendMessage(payload);
108+
// [END_EXCLUDE]
109+
});
110+
// [END receive_message]
111+
112+
function resetUI() {
113+
// Reset UI
114+
clearMessages();
115+
showToken('loading...');
116+
// Get Instance ID token. Initially this makes a network call, once retrieved
117+
// subsequent calls to getToken will return from cache.
118+
// [START get_token]
119+
messaging.getToken()
120+
.then(function(currentToken) {
121+
if (currentToken) {
122+
sendTokenToServer(currentToken);
123+
// Update UI to show token.
124+
updateUIForPushEnabled(currentToken);
125+
} else {
126+
// Show permission request.
127+
console.log('No Instance ID token available. Request permission to generate one.');
128+
// Show permission UI.
129+
updateUIForPushPermissionRequired();
130+
setTokenSentToServer(false);
131+
}
132+
})
133+
.catch(function(err) {
134+
console.log('An error occurred while retrieving token. This may occurr after ' +
135+
'notification permission has been denied. ', err);
136+
setTokenSentToServer(false);
137+
});
138+
}
139+
// [END get_token]
140+
resetUI();
141+
142+
function showToken(currentToken) {
143+
// Show token in console and UI.
144+
var tokenEle = document.querySelector('#token');
145+
tokenEle.textContent = currentToken;
146+
}
147+
148+
// Send the Instance ID token your application server so that you can use it
149+
// to send message to this app. Also you can use the token on the application
150+
// server to subscribe/unsubscribe the token from topics.
151+
function sendTokenToServer(currentToken) {
152+
if (!isTokenSentToServer()) {
153+
console.log('Sending token to server...');
154+
// TODO(developer): Send the current token to your server.
155+
setTokenSentToServer(true);
156+
} else {
157+
console.log('Token already sent to server so won\'t send it again ' +
158+
'unless it changes');
159+
}
160+
161+
}
162+
163+
function isTokenSentToServer() {
164+
if (window.localStorage.getItem('sentToServer') == 1) {
165+
return true;
166+
}
167+
return false;
168+
}
169+
170+
function setTokenSentToServer(sent) {
171+
if (sent) {
172+
window.localStorage.setItem('sentToServer', 1);
173+
} else {
174+
window.localStorage.setItem('sentToServer', 0);
175+
}
176+
}
177+
178+
function showHideDiv(divId, show) {
179+
const div = document.querySelector('#' + divId);
180+
if (show) {
181+
div.style = "display: visible";
182+
} else {
183+
div.style = "display: none";
184+
}
185+
}
186+
187+
function askPermission() {
188+
console.log('Requesting permission...');
189+
// [START request_permission]
190+
messaging.requestPermission()
191+
.then(function() {
192+
console.log('Notification permission granted.');
193+
// [START_EXCLUDE]
194+
// Now you can retrieve a Instance ID token for use with FCM.
195+
resetUI();
196+
// [END_EXCLUDE]
197+
})
198+
.catch(function(err) {
199+
console.log('Unable to get permission to notify.');
200+
});
201+
// [END request_permission]
202+
}
203+
204+
function deleteToken() {
205+
// Delete Instance ID token.
206+
// [START delete_token]
207+
messaging.deleteToken()
208+
.then(function() {
209+
console.log('Token deleted.');
210+
setTokenSentToServer(false);
211+
// [START_EXCLUDE]
212+
// Once token is deleted update UI.
213+
resetUI();
214+
// [END_EXCLUDE]
215+
})
216+
.catch(function(err) {
217+
console.log('Unable to delete token.');
218+
});
219+
// [END delete_token]
220+
}
221+
222+
// Add a messages to the messages element.
223+
function appendMessage(payload) {
224+
const messagesElement = document.querySelector('#messages');
225+
const dataHeaderELement = document.createElement('h5');
226+
const dataElement = document.createElement('p');
227+
dataHeaderELement.textContent = 'Received message:';
228+
dataElement.textContent = JSON.stringify(payload.data);
229+
messagesElement.appendChild(dataHeaderELement);
230+
messagesElement.appendChild(dataElement);
231+
}
232+
233+
// Clear the messages element of all children.
234+
function clearMessages() {
235+
const messagesElement = document.querySelector('#messages');
236+
while (messagesElement.hasChildNodes()) {
237+
messagesElement.removeChild(messagesElement.lastChild);
238+
}
239+
}
240+
241+
function updateUIForPushEnabled(currentToken) {
242+
showHideDiv(tokenDivId, true);
243+
showHideDiv(permissionDivId, false);
244+
showToken(currentToken);
245+
}
246+
247+
function updateUIForPushPermissionRequired() {
248+
showHideDiv(tokenDivId, false);
249+
showHideDiv(permissionDivId, true);
250+
}
251+
</script>
252+
</body>
253+
</html>

0 commit comments

Comments
 (0)