Angularfire: Messaging: TypeError: this.onTokenRefreshInternal is not a function

Created on 5 Sep 2018  Â·  12Comments  Â·  Source: angular/angularfire

Version info

Angular: 6.0.9
Firebase: 5.4.1
AngularFire: 5.0.0-rc.12

How to reproduce these conditions

            const msg: AngularFireMessaging = this.msg;
            msg.tokenChanges.subscribe(
                (token) => console.log('@@@ tokenchange', token),
                (err) => console.log('@@@ tokenchange ERROR', err),
            );

Debug output

* Errors in the JavaScript console *

@@@ tokenchange ERROR TypeError: this.onTokenRefreshInternal is not a function
    at Observable.push../node_modules/@firebase/messaging/dist/index.esm.js.WindowController.onTokenRefresh [as _subscribe] (index.esm.js:1883)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (Observable.js:42)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:28)
    at subscribeTo.js:21
    at subscribeToResult (subscribeToResult.js:6)
    at SwitchMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/switchMap.js.SwitchMapSubscriber._innerSub (switchMap.js:47)
    at SwitchMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/switchMap.js.SwitchMapSubscriber._next (switchMap.js:40)
    at SwitchMapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
    at angularfire2.js:59
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:388)

Expected behavior

No error. Problem seems to be in messaging.ts: https://github.com/angular/angularfire2/blob/185943f60012d8c3dcf7cc26413e3278f9e426be/src/messaging/messaging.ts#L56

    const tokenChanges = this.messaging.pipe(
      switchMap(messaging => new Observable(messaging.onTokenRefresh)),
      runOutsideAngular(zone)
    );

messaging.onTokenRefresh is not bound. As a workaround I've done this myself and this fixes the issue:

                const _messaging = app.messaging();
                _messaging.onTokenRefresh = _messaging.onTokenRefresh.bind(_messaging);

PS. other observables in messaging.ts seem to follow the same pattern and do not bind to this

Most helpful comment

I see, in my quick tests I was calling directly in a module. Seems like it's tripping up while in a service. I'll get the bind patch in and cut 5.0.2 shortly. Thanks for hunting this down everybody!

All 12 comments

Hmmm... interesting. In my test project it seems to be working as expected
but that does sound off and I'll take a peek. I'm also using different
versions of Firebase + Angular.

What's the context in which you're subscribing? A service, component?

On Wed, Sep 5, 2018, 3:34 AM Wilfred van der Deijl notifications@github.com
wrote:

Version info

Angular: 6.0.9
Firebase: 5.4.1
AngularFire: 5.0.0-rc.12
How to reproduce these conditions

        const msg: AngularFireMessaging = this.msg;
        msg.tokenChanges.subscribe(
            (token) => console.log('@@@ tokenchange', token),
            (err) => console.log('@@@ tokenchange ERROR', err),
        );

Debug output

* Errors in the JavaScript console *

@@@ tokenchange ERROR TypeError: this.onTokenRefreshInternal is not a function
at Observable.push../node_modules/@firebase/messaging/dist/index.esm.js.WindowController.onTokenRefresh [as _subscribe] (index.esm.js:1883)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (Observable.js:42)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:28)
at subscribeTo.js:21
at subscribeToResult (subscribeToResult.js:6)
at SwitchMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/switchMap.js.SwitchMapSubscriber._innerSub (switchMap.js:47)
at SwitchMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/switchMap.js.SwitchMapSubscriber._next (switchMap.js:40)
at SwitchMapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
at angularfire2.js:59
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:388)

Expected behavior

No error. Problem seems to be in messaging.ts:
https://github.com/angular/angularfire2/blob/185943f60012d8c3dcf7cc26413e3278f9e426be/src/messaging/messaging.ts#L56

const tokenChanges = this.messaging.pipe(
  switchMap(messaging => new Observable(messaging.onTokenRefresh)),
  runOutsideAngular(zone)
);

messaging.onTokenRefresh is not bound. As a workaround I've done this
myself and this fixes the issue:

            const _messaging = app.messaging();
            _messaging.onTokenRefresh = _messaging.onTokenRefresh.bind(_messaging);

PS. other observables in messaging.ts seem to follow the same pattern and
do not bind to this

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/angular/angularfire2/issues/1855, or mute the thread
https://github.com/notifications/unsubscribe-auth/AACvr7EUL_vtWb4QDKWzpbsmjZ_T0cz1ks5uX6ihgaJpZM4WaoWw
.

Same issue here:

Ionic 3.9.2
Angular: 5.2.3
Firebase: 5.4.2
AngularFire: 5.0.0 release

TypeError: this.onTokenRefreshInternal is not a function
at Observable.webpackJsonp.601.WindowController.onTokenRefresh [as _subscribe] (index.esm.js:1883)
at Observable._trySubscribe (Observable.js:42)
at Observable.subscribe (Observable.js:28)
at subscribeTo.js:21
at subscribeToResult (subscribeToResult.js:11)
at SwitchMapSubscriber._innerSub (switchMap.js:50)
at SwitchMapSubscriber._next (switchMap.js:41)
at SwitchMapSubscriber.Subscriber.next (Subscriber.js:55)
at angularfire2.js:65
at t.invoke (polyfills.js:3)

While doing this in a firebase provider (service)

enableNotifications() {
    this.firebaseMessaging.requestToken.subscribe((token) => {
        console.log("Permission and token granted");
        ...
    })

}

Also fix using same workaround:
messaging.onTokenRefresh = messaging.onTokenRefresh.bind(messaging);

I am having the same issue while subscribing in a service.

However, I cannot get the workaround to work either. I'm not able to get access to the onTokenRefresh method. @cmer4 or @wvanderdeijl can you share a little more context of your workaround? Where are you getting the reference to the messaging or app object?

@bradyisom the messaging with the method can be accessed once you subscribe to the observable i guess:

  initFCMforPWA() {
    navigator.serviceWorker.getRegistration("service-worker.js").then((registration)=>{
      this.firebaseMessaging.messaging.subscribe((messaging)=>{
        // we use this trick here to access useServiceWorker method:
        messaging.useServiceWorker(registration);
        // small workaround below:
        messaging.onTokenRefresh = messaging.onTokenRefresh.bind(messaging);
        // small work around above
        this.enableNotifications();
      });
    })
  };

I got rid of error this way but I have not tested it yet fully. So if you can take a stab at it - great;)

update: well notifications definitely work as just tested this.

@bradyisom the workaround from @cmer4 looks good. Here is another option that works, but pulls in the full firebase SDK, so really only suitable for development. Use try/catch otherwise your app will fail catastrophically on Safari.

import * as app from 'firebase';

@Injectable({
  providedIn: 'root'
})
export class SomeService {
  constructor( ) {
  try {
    const _messaging = app.messaging();
    _messaging.onTokenRefresh = _messaging.onTokenRefresh.bind(_messaging);
    _messaging.onMessage = _messaging.onMessage.bind(_messaging);
  } catch(e) {}

  }
}

Thanks. I used something similar to the workaround by @cmer4. It seems to be working fine for me with the workaround. Seems like binding these functions in the angularfire2 library should fix this issue.

I see, in my quick tests I was calling directly in a module. Seems like it's tripping up while in a service. I'll get the bind patch in and cut 5.0.2 shortly. Thanks for hunting this down everybody!

Fixed in 5.0.2

Facing the same error when subscribing in a component.

Using "firebase": "5.4.2",

Edit: tried the @cmer4 workaround with no luck

Same issue here.
"@angular/core": "6.0.0",
"angularfire2": "5.0.1",
"firebase": "5.4.2",

@chegola i managed to get it working with this..

this.afMessaging.messaging.subscribe(messaging => {
        messaging.onTokenRefresh = messaging.onTokenRefresh.bind(messaging);
        messaging.onMessage = messaging.onMessage.bind(messaging);
..
..
..
        this.afMessaging.messages
                   .subscribe(message => {

@suparnavg @chegola so which version of AngularFire2 you had? As @jamesdaniels mentioned the fix was in 5.0.2 of AngularFire2. So no wonder this issue is present in @chegola 's 5.0.1 version. Or am I missing something?

Was this page helpful?
0 / 5 - 0 ratings