4
votes

I'm trying to receive a push notification token from my app, but I never get a token. I tried debugging using a few alerts, and I can see that I get "granted" returned when accepting notifications. I have only tested for iOS.

i'm running

"expo": "^32.0.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",

I tried using the guide from https://docs.expo.io/versions/latest/guides/push-notifications/

Since it didn't work i tried the snack they provided from the API reference: https://docs.expo.io/versions/v32.0.0/sdk/notifications/

snack: https://snack.expo.io/@documentation/pushnotifications

This is my current code:

 static registerForPushNotificationsAsync = async kid => {
    if (Constants.isDevice) {
      const { status: existingStatus } = await Permissions.getAsync(
        Permissions.NOTIFICATIONS
      );
      let finalStatus = existingStatus;
      if (existingStatus !== "granted") {
        const { status } = await Permissions.askAsync(
          Permissions.NOTIFICATIONS
        );
        finalStatus = status;
      }
      if (finalStatus !== "granted") {
        alert("Failed to get push token for push notification!");
        return;
      }
      let token = await Notifications.getExpoPushTokenAsync();
      alert("finalstatus " + finalStatus);
      alert("existing status " + existingStatus);
      alert(token);
      // POST the token to your backend server from where you can retrieve it to send push notifications.
      return await fetch(`${Api.APIEndpoint}/app/notification`, {
        method: "POST",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          token: token,
          kid: kid
        })
      });
    } else {
      alert("Must use physical device for Push Notifications");
    }
  };

the first two alerts triggers as expected (and returns "granted" when I accept), but alert(token) seems to be empty.

I also noticed that I get asked for two permissions. First it asks for permission to use notifications and then it asks for access to photos. I don't need permissison to photos and I am curious why it asks for that.

As far as I have understood reading the documentation, FCM is required only for android devices? I will need it to work on android as well, but I figured making it work for one platform first and then move on.

I installed the app on my iPhones using Testflight. Does the token only "appear" once the app is approved for the app store?

Maybe there's something else i missed in the documentation.

Any help or point in the right direction will be much appreciated.

2

2 Answers

3
votes

I finally figured this out!

Leaving the solution here in case someone else should have the same problem.

Apparently i had an older version of expo-cli even though i tried updating it many times using npm install -g expo-cli. The command seemed to run fine, but the expo-cli was still the same version.

I tried uninstalling using npm but that seemed to have no effect. The expo-cli was still available. I think it might have been because i installed it before I started to use nvm.

I then decided to manually delete it. I'm running on mac and have no idea if theres a more correct way to uninstall it. But this seemed to work! I deleted /usr/bin/expo and /usr/bin/expo-cli. I then ran npm install -g expo-cli

I then updated the push cert for the app:

expo build:ios --clear-push-cert

I installed the app using testflight on my testdevices, and now I do get a token as expected!

Only thing i'm still curious about is why it asks for permission to access photos.

I hope this can help others with the same problem out there.

Thanks to the ones that took time to read my question.

2
votes

I'm on v34 and was still having this problem in a BIG way. In case it is helpful to anyone in the future, I discovered that using the Permissions.USER_FACING_NOTIFICATIONS first caused the prompt to come up, then I could follow up with Permissions.NOTIFICATIONS, like so:

const { status } = await Permissions.askAsync(Permissions.USER_FACING_NOTIFICATIONS);
const { status2 } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
finalStatus = status2?status2:status;

This did the trick for me. Hope it helps someone else!