开发者问题收集

推送通知、多服务人员?适用于 Web/Android/IOS 和 Firebase 的 Angular Ionic 5 PWA

2020-05-27
2397

我的 Ionic/Angular Capacitor PWA 出了问题。我需要为 Web、Android 和 IOS 设置 PUSH NOTIFICATIONS,但现在只关注 Web。

我已设置 Angular 应用以请求用户通知权限。当他们响应“是”时,我使用他们登录时使用的 firebase uid 在 firestore 中存储令牌。我有一些 firebase 函数,这些函数应该在 firestore db 中创建特定文档类型时触发 onCreate。

我的问题是下一步。无论我在哪里,我都应该设置一个服务工作者来处理通知。但我已经有一个(PWA),我不知道如何设置另一个不会弄乱 PWA sw 的服务工作者。

不知何故,我需要让它跨平台工作。我现在需要让它适用于 Web,但稍后也适用于 android/ionic。

我可以使用多个服务工作者而不会引起问题吗?怎么做? 当我实施 Android/IOS 时,情况会有什么变化? 您能给我提供一些资源吗?

提前谢谢您

1个回答

在现代 Angular (8+) 应用程序中,服务工作线程是在构建时生成的,其 配置是通过位于项目根文件夹中的 ngsw-config.json 文件完成的。

在您的情况下,您需要确保项目的服务工作线程具有 Firebase 导入和传入通知消息处理程序功能。为此,一个策略可以是:

  • 创建另一个 combined-service-worker.js 文件
  • 使用 importScripts('ngsw-worker.js') 使其导入 angular 的服务工作线程;
  • 在您的 app.module.ts 中指向 ServiceWorkerModule 以显式利用 combined-service-worker.js

您的 combined-service-worker.js 可以如下所示:

// IMPORT ANGULAR'S SW:
importScripts('ngsw-worker.js');

// FIREBASE PART:
if (ServiceWorkerRegistration && "pushManager" in ServiceWorkerRegistration.prototype) {

    importScripts('https://www.gstatic.com/firebasejs/7.13.1/firebase-app.js');
    importScripts('https://www.gstatic.com/firebasejs/7.13.1/firebase-messaging.js');

    initializeFirebaseCloudMessaging();

    const messaging = firebase.messaging();

    enableBackGroundMessages();

    function initializeFirebaseCloudMessaging() {

        const FIREBASE_CONFIG = {
            // apiKey: ...
            // etc config for your firebase project
        }

        firebase.initializeApp(FIREBASE_CONFIG);

    };

    function enableBackGroundMessages() {
        messaging.setBackgroundMessageHandler((payload) => {
            const notificationOptions = {
                body: payload.message,
                icon: 'assets/img/mstile-150x150.png'
            };
            return self.registration.showNotification("Morphistic", notificationOptions);
        });
    };

};

您可以在根文件夹中创建此文件,并配置项目的 angular.json 以将其视为“资产”:

       "assets": [
          "src/favicon.ico",
          "src/robot.txt",
          "src/manifest.json",
          "src/combined-service-worker.js",
          {
            "glob": "**/*",
            "input": "src/assets",
            "output": "assets"
          },
          {
            "glob": "**/*.svg",
            "input": "node_modules/ionicons/dist/ionicons/svg",
            "output": "./svg"
          }
        ],

这将确保 combined-service-worker.js 在构建后进入文件夹。

现在,在您的 app.module.ts 中,您可以明确将此工作线程设置为应用程序需要的一个工作线程激活:

...
import { ServiceWorkerModule } from '@angular/service-worker';
...

@NgModule({
  declarations: [
    AppComponent,
    MorphBarComponent
  ],
  imports: [
    IonicModule.forRoot({
      mode: 'ios'
    }),
    AppRoutingModule,
    PipesModule,
    HttpClientModule,
    FormsModule,
    ReactiveFormsModule,
    RouterModule,
    IonicStorageModule.forRoot(),
    ServiceWorkerModule.register('combined-service-worker.js', { enabled: true, registrationStrategy: 'registerImmediately' }),
    BrowserModule,
    HammerModule,
    AngularFireModule.initializeApp(ENV.FIREBASE_CONFIG),
    AngularFireMessagingModule
  ],

稍后,当您获得适用于 iOS/Android 的混合版本时,您可以调整激活策略,这样如果平台是“混合”的,您就可以完全跳过服务工作者注册。

Sergey Rudenko
2020-05-27