eclipsesource / tabris-plugin-firebase

A firebase plugin for Tabris.js
https://tabrisjs.com
BSD 3-Clause "New" or "Revised" License
6 stars 5 forks source link

Token-Changed Event Not Firing on Android #63

Open raphaelpreston opened 5 years ago

raphaelpreston commented 5 years ago

Problem description

When the Firebase token is updated, the on-change event isn't firing on Android.

Environment

Code snippet

/* see existing token */
console.warn("Existing token: " + firebase.Messaging.token);

/* ask for permissions */
if (device.platform == 'iOS') firebase.Messaging.requestPermissions();

/* add on-change event for token */
firebase.Messaging.on('tokenChanged', ({token}) => {
    console.warn("Got updated firebase token: " + token);
});

Output on iOS:

<!-- open app for first time -->
> Existing token: undefined

<!-- confirm or deny notification prompt -->
> Got updated firebase token: ...

Output on Android:

<!-- open app for first time -->
> Existing token: null

<!-- close & restart app -->
> Existing token: ...

Workaround

By setting an interval that repeatedly checks firebase.Messaging.token, you can essentially figure out when the token is updated. This creates needless overhead, though.

mpost commented 5 years ago

The token is not guaranteed to be instantly available on app start. You should therefore rely on the callback (as you do). Is that callback never fired on Android? Did you see the same behavior in the example app?

raphaelpreston commented 5 years ago

Good point Moritz. I wasn't clear enough, but yes, the callback is never fired. This snippet should clear things up.

/* see existing token */
console.warn("Existing token: " + firebase.Messaging.token);

/* add on-change event for token */
firebase.Messaging.on('tokenChanged', ({token}) => {
    console.warn("Got updated firebase token: " + token);
});

let i = 1;
setInterval(() => {
    console.warn("Token check " + (i++) + ": " + firebase.Messaging.token);
}, 1000);

/* ask for permissions */
if (device.platform == 'iOS') firebase.Messaging.requestPermissions();

Outputs

iPhone

> Existing token: undefined
> Token check 1: undefined
> Got updated firebase token: <token>
> Token check 2: <token>
> Token check 3: <token>

Android

> Existing token: null
> Token check 1: <token>
> Token check 2: <token>
> Token check 3: <token>

This is what I was trying to get at with my workaround. Also, I don't recall if I saw the same behavior in the example app.

mpost commented 5 years ago

Since the example app does fire the the event, it could be interesting to check if your app an the google services json or plist files are matching? Is everything correctly installed?

raphaelpreston commented 5 years ago

Not sure what device/OS you are running on that allows the event to fire in the example app, but I've just now tried it on a HTC Desire 530 with Android 6.0.1 and a Pixel 3XL with Android 9 and it doesn't work.

Here's the original code in messaging.js:

firebase.Messaging.on({
      instanceIdChanged: updateMessagingDetails,
      tokenChanged: updateMessagingDetails,
      message: ({data}) => messageText.text = `Message received:\n\n${JSON.stringify(data)}`
    });

    updateMessagingDetails();

    function updateMessagingDetails() {
      let token = firebase.Messaging.token;
      tokenText.text = token ? token : 'Loading token...';
      instanceIdText.text = firebase.Messaging.instanceId;
    }

I modified it slightly to make it clear when it is/isn't firing:

firebase.Messaging.on({
      instanceIdChanged: () => { // modified
          console.log("instanceID changed to " + firebase.Messaging.instanceId);
          updateMessagingDetails();
      },
      tokenChanged: () => { // modified
          console.log("Token changed to " + firebase.Messaging.token);
          updateMessagingDetails();
      },
      message: ({data}) => messageText.text = `Message received:\n\n${JSON.stringify(data)}`
    });

    updateMessagingDetails();

    function updateMessagingDetails() {
      console.log("updateMessagingDetails() called"); // modified
      let token = firebase.Messaging.token;
      tokenText.text = token ? token : 'Loading token...';
      instanceIdText.text = firebase.Messaging.instanceId;
    }

When I build the app (with Tabris at '3.0.0-beta2-dev.20190306' and CLI at '3.0.0-beta2-dev.20190305'), the token still is "Loading Token...", and here is the console output:

As you can see, the event isn't firing.

Upon quitting the app and reloading, the token is displayed in the correct spot.