fechanique / cordova-plugin-fcm

Google FCM Push Notifications Cordova Plugin
623 stars 998 forks source link

FCMPlugin is not defined (before ready) #177

Open aswinramakrish opened 7 years ago

aswinramakrish commented 7 years ago

Is there a ready event, so we can call the functions after it's ready? Because without it, calling FCMPlugin just seems to throw the undefined error. Please see this screenshot -

capture2

jorchg commented 7 years ago

@aswinramakrish Yeah for me it has been a headache too. The only dirty solution I found was to wrap a if (FCMPlugin) with a setInterval. Fast and dirty I know.

aswinramakrish commented 7 years ago

That's exactly what I'm doing. It's a terrible workaround.

maxper75 commented 7 years ago

I thought you could call it from the deviceready event. It works great for me... Which is the problem?

aswinramakrish commented 7 years ago

I'm calling it from the deviceready event. Still getting the above error message.

Baadier-Sydow commented 7 years ago

I'm getting the same error when I run this in device ready.

I've also tried wrapping it in a timeout but all that does is wait until the timeout is over and then it crashes.

Any ideas on a fix?

FWIW I'm running on the latest version of Ionic ie RC3

maxper75 commented 7 years ago

Hi, I don't exactly know what is your setup as I use directly cordova, not ionic, but I have this working exactly as expected. The only thing I may ask you to check is that cordova.js script is loaded before yours, as this is responsible of loading the FCM script. To do this, if they're in head or body (I have both of them in body), put

this way. In yourscript I'd expect something like (function(){ document.addEventListener("deviceready", setupFCM);}); function setupFCM(){

//In my case it is FCMPlugin.getToken(myCallback); } It works great for me, never missed once... 2016-12-06 14:40 GMT+01:00 Baadier Sydow : > I'm getting the same error when I run this in device ready. > > I've also tried wrapping it in a timeout but all that does is wait until > the timeout is over and then it crashes. > > Any ideas on a fix? > > FWIW I'm running on the latest version of Ionic ie RC3 > > — > You are receiving this because you commented. > Reply to this email directly, view it on GitHub > , > or mute the thread > > . > -- Massimiliano Perantoni http://www.perantoni.net tw: maxper75
nicopeeters commented 7 years ago

@Baadier-Sydow did you manage to fix your problem? I'm also experiencing the same issue

Baadier-Sydow commented 7 years ago

@nicopeeters Heya, I changed the if statement to explicitly match the undefined.

              if (typeof FCMPlugin != 'undefined') {
                FCMPlugin.getToken((token) => {
                  console.log(token);
                }, (error) => {
                  console.log('error retrieving token: ' + error);
                });
              }

That's in Typescript.

I'm only using the notifications on the device though.

nicopeeters commented 7 years ago

@Baadier-Sydow . Thank you for the reply. I did eventually manage to fix this by doing a platform check.

   constructor(private platform: Platform) {
    this.platform.ready().then(() => {
        this.initializeApp();
    });
  }

    private initializeApp(): void {
        if (this.platform.is('android') || this.platform.is('ios')) {
            FCMPlugin.getToken(
                (pushRegistrationId: any) => {
                    console.log('Push registration ID: ');
                    console.log(pushRegistrationId);
                },
                (err: any) => {
                    console.log('error retrieving push registration id: ' + err);
                }
            );
        }
    }

I was only getting the not defined message when I was running in browser with ionic serve.

Baadier-Sydow commented 7 years ago

@nicopeeters I was getting the same error in the browser. I'm thinking of trying to integrate the Firebase browser messaging with Javascript to make testing in the browser easier as per the following links:

Cheers

DropkickSteve commented 7 years ago

@maxper75 your suggestions were very useful. I have also placed the FCMPlugin.getToken( ) in the onDeviceReady function but I am receiving weird behavior. Most of the times the token is successfully registered, however sometimes it is not for no apparent reason. I noticed this happening usually during fresh installation of the app. The script that handles the callback is placed after cordova.js as you mentioned, but still no luck. It seems that the initialization time of the plugin varies a lot

imbabaer commented 7 years ago

I can't resolve the 'FCMPlugin is not defined' exception. I installed the plugin and downloaded the google-services.json as mentioned. The workaround with setInterval() didn't work for me.

Any suggestions?

davideas commented 7 years ago

Since FCMPlugin is accessible globally, I added declare let FCMPlugin; after the imports, it started to get the token!

Also add this if statement otherwise ionic serve goes in exception:

if (typeof FCMPlugin != 'undefined') {
    ...
    FCMPlugin.getToken(function (token) {
        console.log(token);
    });
}
savaskalkan commented 7 years ago

you can use on device ready. I got same problem and solve this way.

marcelotadeujr commented 7 years ago

I solved this by doing:

    $rootScope.subscribeToTopic = function(){
        FCMPlugin.subscribeToTopic('allDevices', function(success){
            console.log('FCM Registration: '+success);
        }, function(err){
            console.log('FCM Err: '+ err);
        });
    };

    $rootScope.checkFCM = function(){
        $timeout(function(){
            if(typeof FCMPlugin == 'undefined'){
                $rootScope.checkFCM();
            }else{
                FCMPlugin.onTokenRefresh(function(token){
                    $rootScope.subscribeToTopic();
                });

                FCMPlugin.onNotification(function(data){
                    console.log('data push: ');
                    console.log(data);

                    if(data.wasTapped){
                      alert('Tapped '+JSON.stringify(data) );
                    }else{
                      alert('Foreground: '+JSON.stringify(data) );
                    }
                });

                $rootScope.subscribeToTopic();
            };
        }, 1000);
    };

    $rootScope.checkFCM();
mastran32 commented 7 years ago

Hi everyone, i started using this plugin one week ago but i still can't solve this problem of "FCMPlugin is not defined", instead everything about notifications works fine. I get this error everytime i install the app or delete the app data from my Android System. In this moment i have declared the FCM plugin not in the app.component.ts but in a component called later.

This is an example of what i'm trying to do inside that component:

declare var FCMPlugin;
//other code
//
if (typeof FCMPlugin != 'undefined') {
      FCMPlugin.onTokenRefresh(function (token) {
      //
      });
 }

Do you have an advice to solve this? I tried to use a setInterval without success, @jorchg @aswinramakrish can you show me an example of your setInterval working?

Thanks :)

Baadier-Sydow commented 7 years ago

Not sure if you're using Ionic or not so the general question would be are you doing the type check once the platform is ready.

Justing this quickly as I'm heading out but you could probably do the check like this:

let fcmCheck = setInterval(() => { if (typeof FCMPlugin != 'undefined') { FCMPlugin.onTokenRefresh(function (token) { clearInteval(fcmCheck); // }); } }, 1000);

So it checks each second for the FCM plugin and once it has it then it clears the setInterval.

I've done it using () => {} instead of passing in a function.

Edit: Cant get the formatting right.

mastran32 commented 7 years ago

Tried your solution and for now it's working! I'll let you know if there will be news. Thank you for the support @Baadier-Sydow

mastran32 commented 7 years ago

The problem is still here, i'm using Ionic Live Reload (do you think it can cause the problem?) at the moment and if i clear the app data, sometimes i still get the error. This is what i have done for example for token refresh (code inside a component different from app.component.ts):

  let fcmCheck = setInterval(() => {
      if (typeof FCMPlugin != 'undefined') {
        FCMPlugin.onTokenRefresh(function (token) {
          //
          clearInterval(fcmCheck);
        });
      }
    }, 1000);

Still not checking if the platform is ready anyway. Any ideas? Thanks

Baadier-Sydow commented 7 years ago

Are you using Ionic's wrapper of the FCM plugin?

mastran32 commented 7 years ago

I followed the install instructions of this repo without adding anything else from Ionic (do you mean i need to install some wrapper from Ionic Native)?

Do you think adding a platform ready check could change something? I'm going to try this for now.

this.platform.ready().then(() => {
let fcmCheck = setInterval(() => {
      if (typeof FCMPlugin != 'undefined') {
        FCMPlugin.onTokenRefresh(function (token) {
          //
          clearInterval(fcmCheck);
        });
      }
    }, 1000);
});
Baadier-Sydow commented 7 years ago

So we got it working initially with this plugin then we moved it over to the Ionic Native wrapper for the consistency it provides.

I can share an implementation of either with you as we've done both.

It definitely needs to be after the platform ready though.

We also first ensure the device is registered on FCM by running getToken() then we add a listener that fires onTokenRefresh() for any subsequent refresh events.

mastran32 commented 7 years ago

@Baadier-Sydow It could be really amazing if you could do that because my last code above didn't solve my problems and i have again this error (always when i install the app or delete all data):

Uncaught ReferenceError: FCMPlugin is not defined
    at <anonymous>:1:12
FCMPlugin.js: is created
FCMPlugin Ready OK
Angular is running in the development mode. Call enableProdMode() to enable the production mode.
deviceready has not fired after 5 seconds.
Ionic Native: deviceready did not fire within 5000ms. This can happen when plugins are in an inconsistent state. Try removing plugins from plugins/ and reinstalling them.
Ionic Native: deviceready event fired after 5933 ms

A paste from my console.log, if it can help you to detect the problem. So with Ionic Native wrapper the problem disappear? Can't wait by the way here :D Then i'll share my implementation too to help who will read :)

Baadier-Sydow commented 7 years ago

From the console log it would appear that your code is not in the platform ready as you see the device ready events fire after it.

You need to do your getToken within:

platform.ready().then(() => {

});

We have a function that calls a Push Notification provider once we confirm whether the user is logged in or not.

If the user is logged in we do the following:

  public registerToken() {
    this.fcm.getToken().then(token => {
      console.log(token);
      this.persistToken(token);
      this.subscribeToTokenRefresh();
    }, (error) => {
      console.log('error retrieving token: ' + error);
    });
  }

Most of your issue seems to be that you're calling it before the platform is ready. Using the Ionic Native FCM wrapper will make it easier for you too.

kapilSoni101 commented 4 years ago

@nicopeeters: i tried ur solution but got same error ?

Yadro commented 3 years ago

Hey guys, I've receive the same error. The follow solution doesn't work for me 😞. FCMPlugin is always undefined.

const { Plugins } = await import('@capacitor/core');
const { FCMPlugin } = Plugins;

document.addEventListener('deviceready', () => {
   setInterval(() => {
      console.log(FCMPlugin);
   }, 1000);
})

Anyone have any ideas how to solve it?

Yadro commented 3 years ago

Change MainActivity like here solved the issue.