#javascript #firebase #firebase-cloud-messaging #service-worker
#javascript #firebase #firebase-облако-обмен сообщениями #service-worker
Вопрос:
Я использую firebase для push-уведомлений в Интернете, мой файл firebase-messaging-ws.js
выглядит примерно так:
importScripts('https://www.gstatic.com/firebasejs/7.19.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.19.0/firebase-messaging.js');
fetch('./firebase-data.json')
.then(r => r.json())
.then(fbData => {
let app = firebase.initializeApp(fbData);
firebase.messaging(app);
console.log('Firebase Service Worker loaded for projectId:', fbData.projectId);
}).catch(err => {
console.error('Error configuring firebase messaging: ', err)
});
Я использую файл json firebase-data.json
для загрузки данных конфигурации firebase, и это работает, я могу получать push-уведомления, однако при вызове в консоли появляется несколько предупреждений журнала firebase.messaging()
, если я использую локальный объект (без команды fetch ()), тогда все работает нормально и предупреждающих сообщений нет.
Сообщения журнала похожи Event handler of 'XXX' event must be added on the initial evaluation of worker script.
:
Могу ли я избежать предупреждающих сообщений при использовании внешнего файла для загрузки данных конфигурации firebase?
Ответ №1:
В основном сценарий service worker требует синхронного выполнения, что означает, что вы не можете инициализировать Firebase Messaging в рамках обещания.
Плевок сюда, это непроверено, но попробуйте это:
importScripts('https://www.gstatic.com/firebasejs/7.19.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.19.0/firebase-messaging.js');
const response = await fetch('./firebase-data.json');
const fbData = await response.json();
let app = firebase.initializeApp(fbData);
firebase.messaging(app);
console.log('Firebase Service Worker loaded for projectId:', fbData.projectId);
В качестве альтернативы, если ему не нравится await вне асинхронной функции, используйте JavaScript для экспорта данных конфигурации и используйте importScripts для предоставления их вашему service worker:
firebase-data.js
const fbData = {...};
firebase-messaging-ws.js
importScripts('https://www.gstatic.com/firebasejs/7.19.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.19.0/firebase-messaging.js');
importScripts('./firebase-data.js');
let app = firebase.initializeApp(fbData);
firebase.messaging(app);
console.log('Firebase Service Worker loaded for projectId:', fbData.projectId);
Комментарии:
1. Спасибо, Брайан,
await
opton не имеет никакого значения, однако определение переменнойfbData
в файле js работает нормально.
Ответ №2:
Как объясняется в другом ответе, перемещение fbData
в js
файл позволяет использовать переменную внутри сценария Service Worker.
Просто для записи, я сделал все это, чтобы разделить данные Firebase между областью Service Worker и областью приложения Angular, firebase-data.js
это что-то вроде этого:
const FIREBASE_DATA = {
"apiKey": "***********",
"authDomain": "***********.firebaseapp.com",
"databaseURL": "https://***********.firebaseio.com",
"projectId": "***********",
"storageBucket": "***********.appspot.com",
"messagingSenderId": "***********",
"appId": "1:***************"
}
if (typeof module !== 'undefined') {
module.exports = { ...FIREBASE_DATA }
}
С помощью этой реализации я могу использовать self.FIREBASE_DATA
внутри файла service worker, а также импортировать модуль в мое приложение angualr, например mi environment.ts
, что-то вроде:
import FIREBASE_DATA from "../firebase-data";
export const environment = {
production: true,
url_base: '/api',
firebase: FIREBASE_DATA
};