之前已經
小試身手了,在此把 Web app notification debug 訊息紀錄一下。
1. 關於發 push 要用的 Serverkey 擺在 Firebase -> Project -> Settings -> Project settings -> CLOUD MESSAGING -> Project credentials 的 Server key
2. 初始化 index.html ,請至 Firebase -> Project -> Overview -> Add Firebase to your web app,把他埋在 <head></head> 即可
<script src="https://www.gstatic.com/firebasejs/4.5.2/firebase.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "YourAPIKey",
authDomain: "your-app.firebaseapp.com",
databaseURL: "https://your-app.firebaseio.com",
projectId: "your-app",
storageBucket: "your-app.appspot.com",
messagingSenderId: "your-app-id"
};
firebase.initializeApp(config);
</script>
3. 使用 const messaging = firebase.messaging(); 來操作,如要求收訊權限,取得後則進行要 FCM token:
<script>
const messaging = firebase.messaging();
messaging.requestPermission()
.then(function() {
console.log('Notification permission granted.');
try_to_get_token();
})
.catch(function(err) {
console.log('Unable to get permission to notify.', err);
});
function try_to_get_token() {
messaging.getToken()
.then(function(currentToken) {
if (currentToken) {
console.log("currentToken:", currentToken);
} else {
console.log('No Instance ID token available. Request permission to generate one.');
}
})
.catch(function(err) {
console.log('An error occurred while retrieving token. ', err);
});
}
</script>
4. 開發上請使用 Chrome browser ,想要重置 FCM token 可以在 chrome://settings/content/notifications 將指定網域清除
5. 碰到要不到 FCM token 錯誤訊息
browserErrorMessage: "Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script."
code: "messaging/failed-serviceworker-registration"
message: "Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script. (messaging/failed-serviceworker-registration)."
解法一:在根目錄建置一個空的檔案,檔名為 firebase-messaging-sw.js (最方便的解法)
$ touch /path/www/document_root/firebase-messaging-sw.js
解法二:刻一個 ServiceWorker 處理 (彈性的解法)
$ touch sw.js (與 index.html 同層即可)
$ vim index.html
<script>
const messaging = firebase.messaging();
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('sw.js').then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
messaging.useServiceWorker(registration);
//try_to_get_token();
messaging.requestPermission()
.then(function() {
console.log('Notification permission granted.');
try_to_get_token();
})
.catch(function(err) {
console.log('Unable to get permission to notify.', err);
});
}).catch(function(err) {
//registration failed :(
console.log('ServiceWorker registration failed: ', err);
});
}
</script>
6. 建置收訊息的部分:
前景:
<script>
const messaging = firebase.messaging();
messaging.onTokenRefresh(function() {
console.log("onTokenRefresh");
try_to_get_token();
});
messaging.onMessage(function(payload) {
console.log("Message received. ", payload);
});
if ('serviceWorker' in navigator) {
console.log("test 'serviceWorker' in navigator");
navigator.serviceWorker.register('sw.js').then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
messaging.useServiceWorker(registration);
//try_to_get_token();
messaging.requestPermission()
.then(function() {
console.log('Notification permission granted.');
try_to_get_token();
})
.catch(function(err) {
console.log('Unable to get permission to notify.', err);
});
}).catch(function(err) {
//registration failed :(
console.log('ServiceWorker registration failed: ', err);
});
}
function try_to_get_token() {
messaging.getToken()
.then(function(currentToken) {
if (currentToken) {
console.log("currentToken:", currentToken);
} else {
console.log('No Instance ID token available. Request permission to generate one.');
}
})
.catch(function(err) {
console.log('An error occurred while retrieving token. ', err);
});
}
</script>
背景(/firebase-messaging-sw.js 或是自訂的 ServiceWorker):
$ vim sw.js
// Import and configure the Firebase SDK
// These scripts are made available when the app is served or deployed on Firebase Hosting
// If you do not serve/host your project using Firebase Hosting see https://firebase.google.com/docs/web/setup
importScripts('https://www.gstatic.com/firebasejs/4.5.2/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.5.2/firebase-messaging.js');
importScripts('https://www.gstatic.com/firebasejs/4.5.2/firebase.js');
// Initialize Firebase
var config = {
apiKey: "YourAppApiKey",
authDomain: "your-app.firebaseapp.com",
databaseURL: "https://your-app.firebaseio.com",
projectId: "your-app",
storageBucket: "your-app.appspot.com",
messagingSenderId: "your-app-id"
};
firebase.initializeApp(config);
const messaging = firebase.messaging();
// If you would like to customize notifications that are received in the
// background (Web app is closed or not in browser focus) then you should
// implement this optional method.
// [START background_handler]
messaging.setBackgroundMessageHandler(function(payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
// Customize notification here
const notificationTitle = 'Background Message Title';
const notificationOptions = {
body: 'Background Message body.',
icon: '/firebase-logo.png'
};
return self.registration.showNotification(notificationTitle,
notificationOptions);
});
// [END background_handler]
7. 背景工作補充 /firebase-messaging-sw.js (或是自訂的 ServiceWorker)
當 /firebase-messaging-sw.js (或是自訂的 ServiceWorker) 是空白時,這時 web app (chrome browser) 都到訊息時,只會提醒有訊息在背景更新,且前景都不會觸發 messaging.onMessage 的事件。
8. 若發現異常,例如 Web 前景有 token 又收不到訊息時,請留意背景工作是否有實作,建議把 chrome browser 重開,仍不行時,甚至在 chrome://settings/content/notifications 清除重新來過
9.善用 curl command 測試:
curl -X POST -H "Authorization: key=YourAppServerKey" -H "Content-Type: application/json" -d '{
"notification": {
"title": "Hello",
"body": "World",
"icon": "firebase-logo.png",
"click_action": "http://localhost:8081"
},
"to": "FCM token"
}' "https://fcm.googleapis.com/fcm/send"
10. 若 user 移除接收,送訊息時會收到回饋:
{"multicast_id":####,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"NotRegistered"}]}
11. FCM 跟用戶有沒有登入(Google帳號)無關