我正在使用Firebase在Angular PWA中进行推送通知,我正在关注这样做的链接。 https://medium.com/@tariqueejaz/progressive-web-app-push-notifications-making-the-web-app-more-native-in-nature-a167af22e004
我正在使用Angular 6并为所有内容设置代码。当我试图运行它时,它会向我显示弹出。
单击“允许”按钮后,它在控制台上抛出错误:
无法注册ServiceWorker:获取脚本时收到错误的HTTP响应代码(404)。“ 码 : “消息/失败-serviceworker登记” 信息 : “消息传递:我们无法注册默认服务工作者。无法注册ServiceWorker:获取脚本时收到了错误的HTTP响应代码(404)。(messaging / failed-serviceworker-registration)。” 堆 : “FirebaseError:消息:我们无法注册默认服务工作者。无法注册ServiceWorker:获取脚本时收到错误的HTTP响应代码(404)。(messaging / failed-serviceworker-registration).↵at {{ 3}}↵在ZoneDelegate.push ../ node_modules / zone.js / dist / zone.js.ZoneDelegate.invoke(http://localhost:4200/vendor.js:106604:32)↵在Object.onInvoke(http://localhost:4200/polyfills.js:2710:26)↵在ZoneDelegate.push ../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke( http://localhost:4200/vendor.js:35701:33)↵在Zone.push ../ node_modules / zone.js / dist / zone.js.Zone.run({ {3}})↵在http://localhost:4200/polyfills.js:2709:32↵在ZoneDelegate.push ../ node_modules / zone.js / dist / zone.js.ZoneDelegate.invokeTask(http://localhost:4200/polyfills.js:2460:43)↵在Object.onInvokeTask({{ 3}})↵在Zone.push ../ node_modules / zone.js / dist /的ZoneDelegate.push ../ node_modules / zone.js / dist / zone.js.ZoneDelegate.invokeTask(http://localhost:4200/polyfills.js:3194:34)↵ zone.js.Zone.runTask(http://localhost:4200/polyfills.js:2743:31)“ 的原 : 错误
我的项目结构是: http://localhost:4200/vendor.js:35692:33
我的应用和环境文件夹包含以下文件: http://localhost:4200/polyfills.js:2742:36
我的app.component.ts文件是
import {Component, OnInit} from '@angular/core';
import * as firebase from 'firebase';
import {AngularFireDatabase, AngularFireList} from 'angularfire2/database';
//import {AngularFireDatabase, FirebaseListObservable, FirebaseObjectObservable} from 'angularfire2/database-deprecated';
import {PushService} from './push.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
// Declare the variables used
messaging: any
token: any // Stores the current token ID instance generated
items: AngularFireList<any[]>
itemsDisplay: AngularFireList<any[]> // List observable for template view (Optional. items itself can be used)
itemsArr: any[] // Stores the token IDs retrieved from the firebase database
hideToken: boolean = false
// Notificayion object
pushData: any = {
'notification': {
"title": "Background Message Title",
"body": "Background Message Body"
},
"to": ""
}
constructor(public db: AngularFireDatabase, private pushService: PushService) {
// Creates a Firebase List Observable and calls the data in it
this.itemsDisplay = db.list('/items')
// Declaring the property value of messaging
this.messaging = firebase.messaging();
// Check for token refresh
this.messaging.onTokenRefresh(function() {
this.messaging.getToken()
.then(function(refreshedToken) {
console.log('Token refreshed.');
})
.catch(function(err) {
console.log('Unable to retrieve refreshed token ', err);
});
});
// Obtaining the firebase data and retrieving token ID values separately
this.itemsArr = [] // Reinitialize the array to prevent data duplication
this.items = this.db.list('/items');
this.items.valueChanges().subscribe(snapshots => {
console.log(snapshots);
//snapshots.forEach(snapshot => {
// console.log("Hey ,, snapshot......"+snapshot);
// this.itemsArr.push(snapshot);
// });
});
// console.log(this.itemsArr)
}
// Check for duplicates in token subscription
checkToken(token, arr) {
console.log("Inside check token function")
console.log(arr)
console.log(token)
let counter: number = 0
for (var i = 0; i < arr.length; i++) {
if (arr[i] === token) {
counter++
}
}
console.log("Counter value", counter)
return counter
}
// Generate Push through an event
generatePush() {
console.log("Inside push function")
console.log(this.pushData.to)
if (this.pushData.to === "") {
console.log("No token available")
return
}
this.pushService.generatePush(this.pushData)
.subscribe(data => {console.log("Succesfully Posted")}, err => console.log(err))
}
// Function to get the data from Firebase Database
getDataFromFb() {
this.hideToken = true
}
ngOnInit() {
// Prompt user to grant permission for notifications on loading components
const self = this
this.items = this.db.list('/items')
this.messaging.requestPermission()
.then(function() {
console.log('Notification permission granted.');
self.messaging.getToken()
.then(function(currentToken) {
if (currentToken) {
self.token = currentToken
self.pushData.to = self.token
console.log(self.pushData.to)
// Set a timeout so as to enable all the data to be loaded
setTimeout(() => {
if (self.checkToken(self.token, self.itemsArr) === 0) {
console.log("Push occurrence")
// self.items.push({tokenID: currentToken})
} else {
console.log("User is already subscribed")
}
}, 6500)
// Displays the current token data
console.log("currentToken: ", currentToken);
console.log("Stored token: ", self.token);
} else {
// Show permission request.
console.log('No Instance ID token available. Request permission to generate one.');
}
})
.catch(function(err) {
console.log('An error occurred while retrieving token.', err);
});
})
.catch(function(err) {
console.log('Unable to get permission to notify. ', err);
})
// Handle incoming messages. Called when:
// - a message is received while the app has focus
// - the user clicks on an app notification created by a sevice worker `messaging.setBackgroundMessageHandler` handler.
this.messaging.onMessage(function(payload) {
console.log("Message received. ", payload);
});
}
}
我的firebase-messaging-sw.js文件是:
importScripts('https://www.gstatic.com/firebasejs/3.5.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.5.0/firebase-messaging.js');
firebase.initializeApp({
'messagingSenderId': '850143277209' // run it again show me error
});
var messaging = firebase.messaging();
currentMessage = new BehaviorSubject(null);
// Handle Background Notifications
// 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
messaging.setBackgroundMessageHandler(function (payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
// Customize notification here
var notificationTitle = 'Background Message Title';
var notificationOptions = {
body: 'Background Message body.'
};
return self.registration.showNotification(notificationTitle,
notificationOptions);
});
我的Angular.json文件是:
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"beautyOfSoul": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"@schematics/angular:component": {
"styleext": "scss"
}
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/beautyOfSoul",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets",
"src/assets/manifest.json",
"src/manifest.json",
"src/firebase-messaging-sw.js"
],
"styles": [
"src/styles.scss"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": {
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"serviceWorker": true
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "beautyOfSoul:build"
},
"configurations": {
"production": {
"browserTarget": "beautyOfSoul:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "beautyOfSoul:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"src/styles.scss"
],
"scripts": [],
"assets": [
"src/favicon.ico",
"src/assets",
"src/manifest.json",
"src/firebase-messaging-sw.js"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"beautyOfSoul-e2e": {
"root": "e2e/",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "beautyOfSoul:serve"
},
"configurations": {
"production": {
"devServerTarget": "beautyOfSoul:serve:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "beautyOfSoul"
}
我的网络标签是: http://localhost:4200/polyfills.js:2510:47
我的服务工作者标签是:
答案 0 :(得分:5)
我在React项目中遇到了类似的问题,对我来说,解决方案是手动将自己的js文件注册为服务工作者。
navigator.serviceWorker.register('./your-serviceworker-file.js')
.then((registration) => {
messaging.useServiceWorker(registration);
// Request permission and get token.....
});
在firebase初始化中运行该代码解决了我的问题。