How to setup Expo Push Notifications

Below is a log of kittyUser, a state variable used to store the current user.

{"_actions": 
{"createChannel": "/application/v1/channels.create", "registerDevice": "/application/v1/users/me.devices.register", "update": "/application/v1/users/me.self.update", "updateDisplayPicture": "/application/v1/users/me.display_picture.update"}, "_relays": 
{"channels": "/application/v1/users/me.channels.relay.page..size..sort.", "channelsCount": "/application/v1/users/me.channels.count.relay", "contacts": "/application/v1/users/me.contacts.relay.page..size..sort.", "contactsCount": "/application/v1/users/me.contacts.count.relay", "devices": "/application/v1/users/me.devices.relay.page..size..sort.", "fileAccessGrant": "/application/v1/users/me.write_file_access_grant.relay", "joinableChannels": "/application/v1/users/me.joinable_channels.relay.page..size..sort.", "readFileAccessGrant": "/application/v1/users/me.read_file_access_grant.relay", "self": "/application/v1/users/me.relay", "unreadChannels": "/application/v1/users/me.unread_channels.relay.page..size..sort.", "unreadChannelsCount": "/application/v1/users/me.unread_channels.count.relay", "userBlockListItems": "/application/v1/users/me.user_block_list_items.relay.page..size..sort.", "writeFileAccessGrant": "/application/v1/users/me.write_file_access_grant.relay"}, "_streams": 
{"displayPicture": "/v1/applications/10902/streams/users/me/display_picture"}, "_topics": {"calls": "/user/queue/v1/calls", "channels": "/user/queue/v1/channels", "contacts": "/user/queue/v1/contacts", "devices": "/user/queue/v1/devices", "errors": "/user/queue/v1/errors", "messages": "/user/queue/v1/messages", "notifications": "/user/queue/v1/notifications", "participants": "/user/queue/v1/participants", "self": "/user/queue/v1/self", "users": "/user/queue/v1/users"},
 "displayName": "stevenchews", 
"displayPictureUrl": "https://firebasestorage.googleapis.com:443/v0/b/tennielstagram.appspot.com/cant_show_this", 
"id": 28580, 
"isGuest": true, 
"name": "steven@gmail.com",
 "presence": {"online": true, "status": "AVAILABLE"},
 "properties": {"expo-push-token": "ExponentPushToken[show_cant_this_but_its_correct]"}, "type": "CURRENT"}

User recieved notification cloud function:

const { Expo } = require('expo-server-sdk');

const expo = new Expo(); // create Expo client

async function handleEvent(
  event: UserReceivedNotificationEvent,
  context: Context
) {
  if (event.userHasActiveSession) return; // skip if this user is online

  const expoPushToken = event.user.properties['expo-push-token']; // get the expo push token registered

  if (!expoPushToken || !Expo.isExpoPushToken(expoPushToken)) return; // check expo push token is present and valid

  const notification = event.notification;

  // send push notification with Expo
  await expo.sendPushNotificationsAsync([
    {
      to: expoPushToken,
      sound: 'default',
      title: notification.title,
      body: notification.body,
      data: notification.data,
    },
  ]);
}

My beta testers were telling me that they were not receiving push notifications when signed out, of my app or signed in. Please help!

1 Like

Hey @stevenchews, thank you for making the first post on ChatKitty Community!

About your question, can you confirm that your User Received Notification chat function is being triggered? And if so, that your Expo client is sending the push notification.

One of the succeeded logs

{
  "notification": {
    "id": 114610,
    "body": "Yoyo",
    "data": {
      "type": "USER:SENT:MESSAGE",
      "_relays": {
        "message": "/application/v1/messages/30565.relay"
      },
      "message": {
        "id": 30565,
        "body": "Yoyo",
        "type": "TEXT",
        "user": {
          "id": 28952,
          "name": "johntchou@gmail.com",
          "type": "PERSON",
          "presence": {
            "online": true,
            "status": "AVAILABLE"
          },
          "properties": {},
          "displayName": "chou_mein",
          "displayPictureUrl": "https://firebasestorage.googleapis.com/dfgsdgsdfg"
        },
        "links": [],
        "_relays": {
          "self": "/application/v1/messages/30565.relay",
          "user": "/application/v1/users/28952.relay",
          "likes": "/application/v1/messages/30565.likes.relay.page..size..sort.",
          "thread": "/application/v1/threads/37053.relay",
          "channel": "/application/v1/channels/37053.relay",
          "reactions": "/application/v1/messages/30565.reactions.relay.page..size..sort.",
          "readReceipt": "/application/v1/messages/30565.read_receipt.relay",
          "readReceipts": "/application/v1/messages/30565.read_receipts.relay.page..size..sort.",
          "deliveryReceipt": "/application/v1/messages/30565.delivery_receipt.relay",
          "deliveryReceipts": "/application/v1/messages/30565.delivery_receipts.relay.page..size..sort."
        },
        "_topics": {
          "likes": "/topic/v1/messages/30565.likes",
          "reactions": "/topic/v1/messages/30565.reactions",
          "readReceipts": "/topic/v1/messages/30565.read_receipts",
          "deliveryReceipts": "/topic/v1/messages/30565.delivery_receipts"
        },
        "content": [],
        "_actions": {
          "like": "/application/v1/messages/30565.like",
          "read": "/application/v1/messages/30565.read",
          "react": "/application/v1/messages/30565.react",
          "delete": "/application/v1/messages/30565.delete",
          "unlike": "/application/v1/messages/30565.unlike",
          "deleteForMe": "/application/v1/messages/30565.delete_for_me",
          "removeReaction": "/application/v1/messages/30565.remove_reaction"
        },
        "properties": {},
        "createdTime": "2021-06-19T20:04:42.502Z"
      },
      "channelId": 37053,
      "recipient": {
        "id": 29003,
        "name": "dfgdfgsdfgs@gmail.com",
        "type": "CURRENT",
        "links": [],
        "_relays": {
          "self": "/application/v1/users/me.relay",
          "devices": "/application/v1/users/me.devices.relay.page..size..sort.",
          "channels": "/application/v1/users/me.channels.relay.page..size..sort.",
          "contacts": "/application/v1/users/me.contacts.relay.page..size..sort.",
          "channelsCount": "/application/v1/users/me.channels.count.relay",
          "contactsCount": "/application/v1/users/me.contacts.count.relay",
          "unreadChannels": "/application/v1/users/me.unread_channels.relay.page..size..sort.",
          "fileAccessGrant": "/application/v1/users/me.write_file_access_grant.relay",
          "joinableChannels": "/application/v1/users/me.joinable_channels.relay.page..size..sort.",
          "userBlockListItems": "/application/v1/users/me.user_block_list_items.relay.page..size..sort.",
          "readFileAccessGrant": "/application/v1/users/me.read_file_access_grant.relay",
          "unreadChannelsCount": "/application/v1/users/me.unread_channels.count.relay",
          "writeFileAccessGrant": "/application/v1/users/me.write_file_access_grant.relay"
        },
        "_topics": {
          "self": "/user/queue/v1/self",
          "calls": "/user/queue/v1/calls",
          "users": "/user/queue/v1/users",
          "errors": "/user/queue/v1/errors",
          "devices": "/user/queue/v1/devices",
          "channels": "/user/queue/v1/channels",
          "contacts": "/user/queue/v1/contacts",
          "messages": "/user/queue/v1/messages",
          "participants": "/user/queue/v1/participants",
          "notifications": "/user/queue/v1/notifications"
        },
        "content": [],
        "_actions": {
          "update": "/application/v1/users/me.self.update",
          "createChannel": "/application/v1/channels.create",
          "registerDevice": "/application/v1/users/me.devices.register",
          "updateDisplayPicture": "/application/v1/users/me.display_picture.update"
        },
        "_streams": {
          "displayPicture": "/v1/applications/10902/streams/users/me/display_picture"
        },
        "presence": {
          "online": false,
          "status": "UNAVAILABLE"
        },
        "properties": {},
        "displayName": "asdfasdf",
        "displayPictureUrl": "https://firebasestorage.googleapis.com/vasdfasdfasdf"
      }
    },
    "links": [],
    "title": "chosdfu_mdfsdfein sent a message",
    "content": [],
    "createdTime": "2021-06-19T20:04:42.563Z"
  },
  "userHasActiveSession": false,
  "user": {
    "id": 29003,
    "name": "sdfgsdfg@gmail.com",
    "type": "PERSON",
    "links": [],
    "_relays": {
      "self": "/application/v1/users/29003.relay",
      "channelMember": "/application/v1/users/29003.channel_member.relay"
    },
    "content": [],
    "_actions": {
      "block": "/application/v1/users/29003.block"
    },
    "presence": {
      "online": false,
      "status": "UNAVAILABLE"
    },
    "properties": {},
    "displayName": "asdfasdfssdf",
    "displayPictureUrl": "https://firebasestorage.googleapis.com/v0asdfasdfasdf"
  }
}```

Looks like your chat function is working correctly. So it’s a problem related to Expo.

It might be related to Expo API changes.

Check out this topic. Expo Push Notifications Not Working - #20 by kani - Help: Expo SDK - Forums

Okay I tried testing the expo token on expo’s notification tool and that works. I also tested the code below and it works fine as well… how should i go from here? I also attached more from the cloud function response below if you could help, thank you! :sob:

//This works
export async function schedulePushNotification() {
  await Notifications({
    content: {
      sound: 'notification.wav',
      title: "You've got mail! 📬",
      body: 'Here is the notification body',
      data: {data: 'goes here'},
    },
    trigger: {seconds: 2},
  });
}

//This works
export async function sendPushNotification() {
  const message = {
    to: 'ExponentPushToken[sdfsdfsdfsdfsdfdfgdfg]',
    sound: 'default',
    title: 'title',
    body: 'hello body',
  };

  await fetch('https://exp.host/--/api/v2/push/send', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Accept-encoding': 'gzip, deflate',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(message),
  })
    .then(res => console.log(res))
    .catch(err => console.log(err));
}

Response from cloud function


  "notification": {
    "id": 114667,
    "body": "Ffdf",
    "data": {
      "type": "USER:SENT:MESSAGE",
      "_relays": {
        "message": "/application/v1/messages/30615.relay"
      },
      "message": {
        "id": 30615,
        "body": "Ffdf",
        "type": "TEXT",
        "user": {
          "id": 28953,
          "name": "person1@gmail.com",
          "type": "PERSON",
          "presence": {
            "online": true,
            "status": "AVAILABLE"
          },
          "properties": {
            "expo-push-token": "ExponentPushToken[person1token]"
          },
          "displayName": "kakashi69",
          "displayPictureUrl": "https://firebasestorage.googleapisimages%2Fnp29FP6z3hVn6jvEIfVFk9iv02p1%2F5EFE16ED-3F2F-4C74-8B59-1A350B79843"
        },
        "links": [],
        "_relays": {
          "self": "/application/v1/messages/30615.relay",
          "user": "/application/v1/users/28953.relay",
          "likes": "/application/v1/messages/30615.likes.relay.page..size..sort.",
          "thread": "/application/v1/threads/37104.relay",
          "channel": "/application/v1/channels/37104.relay",
          "reactions": "/application/v1/messages/30615.reactions.relay.page..size..sort.",
          "readReceipt": "/application/v1/messages/30615.read_receipt.relay",
          "readReceipts": "/application/v1/messages/30615.read_receipts.relay.page..size..sort.",
          "deliveryReceipt": "/application/v1/messages/30615.delivery_receipt.relay",
          "deliveryReceipts": "/application/v1/messages/30615.delivery_receipts.relay.page..size..sort."
        },
        "_topics": {
          "likes": "/topic/v1/messages/30615.likes",
          "reactions": "/topic/v1/messages/30615.reactions",
          "readReceipts": "/topic/v1/messages/30615.read_receipts",
          "deliveryReceipts": "/topic/v1/messages/30615.delivery_receipts"
        },
        "content": [],
        "_actions": {
          "like": "/application/v1/messages/30615.like",
          "read": "/application/v1/messages/30615.read",
          "react": "/application/v1/messages/30615.react",
          "delete": "/application/v1/messages/30615.delete",
          "unlike": "/application/v1/messages/30615.unlike",
          "deleteForMe": "/application/v1/messages/30615.delete_for_me",
          "removeReaction": "/application/v1/messages/30615.remove_reaction"
        },
        "properties": {},
        "createdTime": "2021-06-20T00:11:25.345Z"
      },
      "channelId": 37104,
      "recipient": {
        "id": 28580,
        "name": "person2@gmail.com",
        "type": "CURRENT",
        "links": [],
        "_relays": {
          "self": "/application/v1/users/me.relay",
          "devices": "/application/v1/users/me.devices.relay.page..size..sort.",
          "channels": "/application/v1/users/me.channels.relay.page..size..sort.",
          "contacts": "/application/v1/users/me.contacts.relay.page..size..sort.",
          "channelsCount": "/application/v1/users/me.channels.count.relay",
          "contactsCount": "/application/v1/users/me.contacts.count.relay",
          "unreadChannels": "/application/v1/users/me.unread_channels.relay.page..size..sort.",
          "fileAccessGrant": "/application/v1/users/me.write_file_access_grant.relay",
          "joinableChannels": "/application/v1/users/me.joinable_channels.relay.page..size..sort.",
          "userBlockListItems": "/application/v1/users/me.user_block_list_items.relay.page..size..sort.",
          "readFileAccessGrant": "/application/v1/users/me.read_file_access_grant.relay",
          "unreadChannelsCount": "/application/v1/users/me.unread_channels.count.relay",
          "writeFileAccessGrant": "/application/v1/users/me.write_file_access_grant.relay"
        },
        "_topics": {
          "self": "/user/queue/v1/self",
          "calls": "/user/queue/v1/calls",
          "users": "/user/queue/v1/users",
          "errors": "/user/queue/v1/errors",
          "devices": "/user/queue/v1/devices",
          "channels": "/user/queue/v1/channels",
          "contacts": "/user/queue/v1/contacts",
          "messages": "/user/queue/v1/messages",
          "participants": "/user/queue/v1/participants",
          "notifications": "/user/queue/v1/notifications"
        },
        "content": [],
        "isGuest": true,
        "_actions": {
          "update": "/application/v1/users/me.self.update",
          "createChannel": "/application/v1/channels.create",
          "registerDevice": "/application/v1/users/me.devices.register",
          "updateDisplayPicture": "/application/v1/users/me.display_picture.update"
        },
        "_streams": {
          "displayPicture": "/v1/applications/10902/streams/users/me/display_picture"
        },
        "presence": {
          "online": true,
          "status": "AVAILABLE"
        },
        "properties": {
          "expo-push-token": "ExponentPushToken[person2token]"
        },
        "displayName": "stevenchews",
        "displayPictureUrl": "https://firebasestorage.googleapis.com:44images%2Fsteve76035.jpg?alt=media&token=20b2c6e4-d138-c770885294aa"
      }
    },
    "links": [],
    "title": "kakashi69 sent a message",
    "content": [],
    "createdTime": "2021-06-20T00:11:25.394Z"
  },
  "userHasActiveSession": true,
  "user": {
    "id": 28580,
    "name": "person2@gmail.com",
    "type": "PERSON",
    "links": [],
    "_relays": {
      "self": "/application/v1/users/28580.relay",
      "channelMember": "/application/v1/users/28580.channel_member.relay"
    },
    "content": [],
    "isGuest": true,
    "_actions": {
      "block": "/application/v1/users/28580.block"
    },
    "presence": {
      "online": true,
      "status": "AVAILABLE"
    },
    "properties": {
      "expo-push-token": "ExponentPushToken[person2token]"
    },
    "displayName": "stevenchews",
    "displayPictureUrl": "https://firebasestorage.googleapis.com:443/v0/b/tennielstagram.app70885294aa"
  }
}
1 Like

I tried looking into the link you sent as well but that app.json config is for Android unfortunately, I am mainly focused on ios

Interesting. Seems like an issue with the version of expo-server-sdk you have installed on your chat runtime.

  const message = {
    to: event.user.properties['expo-push-token'],
    sound: 'default',
    title: notification.title,
    body: notification.body,
    data: notification.data,
  };

  await axios.request({
    url: 'https://exp.host/--/api/v2/push/send',
    headers: {
      Accept: 'application/json',
      'Accept-encoding': 'gzip, deflate',
      'Content-Type': 'application/json',
    },
    data: JSON.stringify(message),
  });

You can use this directly in your chat function. Since you’ve established that it works.