代码之家  ›  专栏  ›  技术社区  ›  N Sharma

Angular注册ServiceWorker失败:获取脚本时收到错误的HTTP响应代码(404)

  •  4
  • N Sharma  · 技术社区  · 8 年前

    我正在使用firebase在angular pwa中执行推送通知,我正在跟踪一个链接。 https://medium.com/@tariqueejaz/progressive-web-app-push-notifications-making-the-web-app-more-native-in-nature-a167af22e004

    我用的是Angular6,已经为所有的东西设置了代码。当我试着运行它时,它会显示一个弹出窗口 enter image description here .

    单击“允许”按钮后,将在控制台上引发错误:

    注册ServiceWorker失败:获取脚本时收到错误的HTTP响应代码(404)。” 代码 : “消息/服务工作者注册失败” 消息 : “消息:我们无法注册默认的服务工作者。注册ServiceWorker失败:获取脚本时收到错误的HTTP响应代码(404)。(消息/ServiceWorker注册失败)。” 堆栈 : “firebaseerror:messaging:我们无法注册默认服务工作进程。注册ServiceWorker失败:获取脚本时收到错误的HTTP响应代码(404)。(消息/ServiceWorker注册失败)。在 http://localhost:4200/vendor.js:106604:32 在zoneDelegate.push../node_modules/zone.js/dist/zone.js.zoneDelegate.invoke( http://localhost:4200/polyfills.js:2710:26 )–μat object.onInvoke( http://localhost:4200/vendor.js:35701:33 )在zoneDelegate.push../node_modules/zone.js/dist/zone.js.zoneDelegate.invoke( http://localhost:4200/polyfills.js:2709:32 )–_μat zone.push../node_modules/zone.js/dist/zone.js.zone.run( http://localhost:4200/polyfills.js:2460:43 )-_ http://localhost:4200/polyfills.js:3194:34 在zonedelegate.push../node_modules/zone.js/dist/zone.js.zonedelegate.invoketask( http://localhost:4200/polyfills.js:2743:31 )在object.onInvokeTask( http://localhost:4200/vendor.js:35692:33 )在zonedelegate.push../node_modules/zone.js/dist/zone.js.zonedelegate.invoketask( http://localhost:4200/polyfills.js:2742:36 )在zone.push../node_modules/zone.js/dist/zone.js.zone.runtask( http://localhost:4200/polyfills.js:2510:47 ) 原始的 : 误差

    我的项目结构是: enter image description here

    我的应用程序和环境文件夹包含以下文件: enter image description here

    我的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"
    }
    

    我的网络选项卡是: enter image description here

    我的服务人员标签是:

    enter image description here

    1 回复  |  直到 8 年前
        1
  •  6
  •   Mirko Flyktman    8 年前

    我在react项目中遇到了类似的问题,对我来说,解决方案是手动注册我自己的js文件作为一个服务工作者。

    navigator.serviceWorker.register('./your-serviceworker-file.js')
    .then((registration) => {
      messaging.useServiceWorker(registration);
    
      // Request permission and get token.....
    });
    

    在firebase初始化中运行该代码为我解决了这个问题。

    推荐文章