Skip to content

AngularFireMessaging is not compatible with the Angular Service Worker聽#34352

Closed

Description

@ConsultDarryl

馃殌 feature request

This feature request is for @angular/pwa

Description

If you are using the Angular Service Worker, you are not currently able to use AngularFireMessaging. If you'd like this feature please file an issue in either repository. Your alternatives are to use WorkboxJS or just simply use the Firebase Messaging Service Worker, which is detailed below.

Describe alternatives you've considered

I am following these instructions but would prefer to have one SW to rule them all.
https://angularfirebase.com/snippets/how-to-use-a-firebase-fcm-service-worker-with-angular-s-ngsw-service-worker/

Activity

  1. added this to the needsTriage milestone on Dec 11, 2019
  2. spock123 commented on Dec 12, 2019

    @spock123

    Yeah I'm in the same situation, wanting to use Firebase (AnguilarFire) for messaging, finding it doesn't play well with the Angular Service Worker..

  3. added
    featureLabel used to distinguish feature request from other issues
    on Dec 12, 2019
  4. modified the milestones: needsTriage, Backlog on Dec 12, 2019
  5. hcassar93 commented on Dec 25, 2019

    @hcassar93
  6. davidzwa commented on Dec 31, 2019

    @davidzwa

    In the same situation. Currently having to add my own .js to overrule the Angular SW, which is very against my principles (100% .TS).
    Also I have to skip DI:

    export class NotificationRealService implements INotificationService {
        messaging;
        fcmToken: string;
        currentMessage = new BehaviorSubject(null);
    
        // Dont DI inject firebase messaging if you want Brave to work (meh)
        constructor(@Inject(HTTP_CLIENT) private http: HttpClient,
                    @Inject('API_URL') private apiUrl: string,
                    @Inject('API2_URL') private api2Url: string,
                    @Inject(SNACKBAR_SERVICE) private snackBarService: SnackBarService,
                    @Inject(USER_SERVICE) private userService: UserService) {
            if (!firebase.apps.length) {
                firebase.initializeApp(environment.firebase);
                this.messaging = firebase.messaging();
                navigator.serviceWorker.getRegistration().then(swr => firebase.messaging().useServiceWorker(swr));
            }
        }
    
  7. N-Andronopoulos commented on Jan 15, 2020

    @N-Andronopoulos

    Related to #26413

  8. johanchouquet commented on Apr 17, 2020

    @johanchouquet
    Contributor

    Hi there,

    What's the status of this issue please ?

    Thanks a lot!

  9. floogulinc commented on May 5, 2020

    @floogulinc

    Now that the Angular service worker has its own support for push notifications will that allow for using FCM with it?

  10. dhrn commented on May 11, 2020

    @dhrn
  11. davidzwa commented on May 13, 2020

    @davidzwa

    I found this recent blog https://blog.angular-university.io/angular-push-notifications/
    with this github repo (note the branch) https://github.com/angular-university/angular-pwa-course/tree/1-notifications-finished.

    I'd keep your implementation as FCM-less as possible: use a VAPID key and let SwPush figure out the rest:

    https://github.com/angular-university/angular-pwa-course/blob/1-notifications-finished/src/app/lessons/lessons.component.ts

    I for one will be removing my firebase installs + sw override, because it is a great pain so far in Angular.

  12. razfriman commented on Jul 16, 2020

    @razfriman

    Would love this as well

  13. 11 remaining items

  14. rubenheymans commented on Jan 5, 2021

    @rubenheymans

    Don't we all need FCM in our PWA though? (Not just on the web) How come this is not working, they are 2 Google products.
    How can we help to speed up this process?

  15. jaspervanmegroot commented on Jan 13, 2021

    @jaspervanmegroot

    Hi

    Got AngularFire to work with angular sw fairly easily using https://medium.com/kabbage-engineering/angular-pwa-app-notification-using-firebase-cloud-messaging-d1b7bd171b98. And using the new API getToken. Not to forget the amendments to the manifest. But for the rest, peace of cake.

    In fact, I believe the readme should not say it is impossible. It just uses the default firebase sw which you need to overrule.

    Snippets of code:

    package.json
      "@angular/fire": "^6.1.4",
      "firebase": "^7.0 || ^8.0",
      "@angular/service-worker": "~10.0.0",
          
        
    
    
    import { FirebaseApp } from '@angular/fire';
    
    ....
    
      constructor(
        private swUpdate: SwUpdate,
        private swPush: SwPush,
        private firebase: FirebaseApp,
      ) { }
    
    ....
    
        const serviceWorkerRegistration = await navigator.serviceWorker.getRegistration();
        const messaging = this.firebase.messaging();
        console.log('MESSAGING SW', serviceWorkerRegistration);
        messaging.getToken({
          vapidKey:
            'BEYQVzBmAoN4......X0mpSy9sHSinAHyhBT534cwwrkr49A1qqNg-M',
          serviceWorkerRegistration  // this should be the fix for angularfire not working with ngsw
        }
        ).then((currentToken) => {
          console.log('TOKEN', currentToken);
    
          this.swPush.messages.subscribe(msg => console.log('push message', msg));
          this.swPush.notificationClicks.subscribe(click => console.log('notification click', click));
    
      ....
    

    Do you maybe have an example on Github?

  16. Tommertom commented on Jan 13, 2021

    @Tommertom

    Do you maybe have an example on Github?

    Sorry, no full working app example on shareable Github (private project), but if you create a Stackblitz, happy to look at where you getting stuck and add PWA code as intended in earlier post.

    ps you are aware the Firebase Messaging SDK does not work on iOS devices?

  17. jornetsimon commented on Feb 23, 2021

    @jornetsimon

    To avoid any confusion regarding the deleted comment from yesterday, it is perfectly right to use a common value (e.g. 103953800507) for gcm_sender_id in the manifest.
    Source : Frank van Puffelen, Engineer at Firebase

  18. rewtelize commented on Mar 2, 2021

    @rewtelize

    Hello all, can anyone tell me why AngularFireMessaging is not compatible with the Angular Service Worker and what's the impact of having both working simultaneously?

  19. Tommertom commented on Mar 2, 2021

    @Tommertom

    Hello all, can anyone tell me why AngularFireMessaging is not compatible with the Angular Service Worker and what's the impact of having both working simultaneously?

    Reading for the responses before and the renewed README on AngularFire messaging you can see it IS compatible and works flawlessly with the Angular service worker. You just need to configure it to use it.

    I cant comment on having two service workers besides each other, but plainly for messaging and e.g. offline support, there is no need to have two.

    The AngularFire team may do themselves a favour and posting a blog on blog.angular.io saying how cool it all works with the Angular service worker

  20. rewtelize commented on Mar 5, 2021

    @rewtelize

    First of all, thanks for your answer @Tommertom :)

    But I'm working with Azure Notification Hub, and in order to create or update an installation/register based on any device, I need to send its device's token as a handle. Using AngularFireMessaging was easy because I could just call requestToken() and I got it. On the other hand, using Push API I got a PushSubscription object, which contains an endpoint, a pair of keys and an expirationTime.

    Is there a way to register a device using a PushSubscription object?

  21. Cironic commented on Mar 12, 2021

    @Cironic

    Hi

    Got AngularFire to work with angular sw fairly easily using https://medium.com/kabbage-engineering/angular-pwa-app-notification-using-firebase-cloud-messaging-d1b7bd171b98. And using the new API getToken. Not to forget the amendments to the manifest. But for the rest, peace of cake.

    In fact, I believe the readme should not say it is impossible. It just uses the default firebase sw which you need to overrule.

    Snippets of code:

    package.json
      "@angular/fire": "^6.1.4",
      "firebase": "^7.0 || ^8.0",
      "@angular/service-worker": "~10.0.0",
          
        
    
    
    import { FirebaseApp } from '@angular/fire';
    
    ....
    
      constructor(
        private swUpdate: SwUpdate,
        private swPush: SwPush,
        private firebase: FirebaseApp,
      ) { }
    
    ....
    
        const serviceWorkerRegistration = await navigator.serviceWorker.getRegistration();
        const messaging = this.firebase.messaging();
        console.log('MESSAGING SW', serviceWorkerRegistration);
        messaging.getToken({
          vapidKey:
            'BEYQVzBmAoN4......X0mpSy9sHSinAHyhBT534cwwrkr49A1qqNg-M',
          serviceWorkerRegistration  // this should be the fix for angularfire not working with ngsw
        }
        ).then((currentToken) => {
          console.log('TOKEN', currentToken);
    
          this.swPush.messages.subscribe(msg => console.log('push message', msg));
          this.swPush.notificationClicks.subscribe(click => console.log('notification click', click));
    
      ....
    

    I tried building a porject like the one in the article that you posted. I struggle at the following point:
    if (!firebase.apps.length) { firebase.initializeApp(environment.firebase); navigator.serviceWorker.getRegistration().then(swr=> firebase.messaging().useServiceWorker(swr)); }

    I saw you edited the constructor at the point quite a lot, but I can't figure out how to get it to work, even with your code snippets.
    firebase.messaging().useServiceWorker(swr) in this line as swr is coming undefined inside getRegistration().then(swr).
    if you could tell me how to fix the problem I would be really glad...

  22. gkalpak commented on Mar 12, 2021

    @gkalpak
    Member

    @Cironic, this might happen because the SW might not have been registered yet (it depends on the registrationStrategy). You could listener to controllerchange events before retrieving the SW registration; something like:

    import {fromEvent, of} from 'rxjs';
    import {filter, map, startWith, switchMap, take} from 'rxjs/operators';
    
    // ...
    const swRegistration$ = fromEvent(navigator.serviceWorker, 'controllerchange').pipe(
        startWith(null),
        map(() => navigator.serviceWorker.controller),
        filter((c): c is ServiceWorker => !!c),
        // Uncomment the following line if you only need the first value. 
        // take(1),
        switchMap(() => navigator.serviceWorker.getRegistration()),
    );
    
    swRegistration$.subscribe(reg => /* Pass `reg` to Firebase messaging. */);
  23. Cironic commented on Mar 15, 2021

    @Cironic

    @gkalpak, I hope you can help me, since I don't really get how to use your code in the example of the medium article.
    Since the problem occurs in the constructor. EDIT: it worked all fine with @angular-devkit/build-angular": "~0.803.12"

    export class AppComponent {
      displayToken: string;
      constructor(updates: SwUpdate, push: SwPush) {
        updates.available.subscribe(_ => updates.activateUpdate().then(() => {
          console.log('reload for update');
          document.location.reload();
        }));
        push.messages.subscribe(msg => console.log('push message', msg));
        push.notificationClicks.subscribe(click => console.log('notification click', click));
        if (!firebase.apps.length) {
          firebase.initializeApp(environment.firebase);
          navigator.serviceWorker.getRegistration().then(swr => firebase.messaging().useServiceWorker(swr));
        }
      }
    

    And maybe you can answer me another question:
    for Firebase messaging implementation is it correct to register the ngsw-worker as Serviceworker and not the firebase-messaging-sw?

    ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
    

    And I guess here I could use another registrationStrategy so I don't have to use your code?

    Sorry for all the questions, but you are my best bet right now to keep progressing on my project.

  24. gkalpak commented on Mar 16, 2021

    @gkalpak
    Member

    for Firebase messaging implementation is it correct to register the ngsw-worker as Serviceworker and not the firebase-messaging-sw?

    I'not familiar with Firebase messaging tbh, but that is my understanding from a quick look at the article and the Firebase docs.

    And I guess here I could use another registrationStrategy so I don't have to use your code?

    I don't think any registration strategy would make it safe to not use my code 馃槢
    The SW registration is always an async operation.

  25. gkalpak commented on Apr 7, 2021

    @gkalpak
    Member

    AFAICT, the latest version of AnguarFireMessaging (AFM) is compatible with the Angular ServiceWorker (NGSW). The AngularFire team is working on documenting how to configure AFM to work with NGSW. For more details see angular/angularfire#1923 (reply in thread).

    Based on that, I am going to close this issue. If there is anything else that needs to be fixed in the NGSW, please open a new issue.

  26. angular-automatic-lock-bot commented on May 8, 2021

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  27. locked and limited conversation to collaborators on May 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: service-workerIssues related to the @angular/service-worker packagefeatureLabel used to distinguish feature request from other issues

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions