Notification sent to wrong devices/users

Our team is experiencing an issue with your push notification service.

Useful Info:

The Problem:

There have been several times notifications were delivered to the wrong user/device. We are 100% sure we are retrieving the correct expo push tokens server side to send to. This has been tested and confirmed.

Context:

We went through the client side code and realized we were not passing an “experienceId” when calling Notifications.getExpoPushTokenAsync. This has since been corrected. This project belongs to an organization, and we are now doing:

const experienceId = @${Constants.manifest.owner}/${Constants.manifest.slug};

Is this now correct?

Could a missing experienceId cause notifications to be delivered to the wrong user/device?

Finally:

Concerning the experienceId, the docs say here (Notifications - Expo Documentation), if not supplied, it defaults to Constants.manifest.id, but I get a deprecation warning for Constants.manifest.id.

Deprecation Warning;

Prefer projectId or originalFullName instead for identification and scopeKey for scoping due to immutability.

Any help with this would be greatly appreciated!

Thanks,

Hi!

Sorry you’re seeing this issue- your correction to passing the experienceId manually is a good one, although I don’t believe that the previous setup would result in sending notifications to the wrong device (notifications are sent based on both the underlying device push token and the experience ID).

How have you determined that notifications are sent to the wrong device? By collecting a token from device A, sending one single notification (to that token), andthen a notification is received by device B?

We will be moving to project IDs soon, but for now your current experienceId setup is correct.

Thank you for the speedy response!

Our backend is using Laravel. Again we are using a package recommended in the docs to send notifications. (GitHub - Alymosul/exponent-server-sdk-php: Server-side library for working with Expo push notifications using PHP)

We have a heavily event driven application with well defined relationships that has been running for a couple years now, which is why we are confident we are retrieving the correctly scoped users/devices to send to. It’s simple, and roughly as so:

$expo = Expo::normalSetup();
$account = $event->account;

// Only retrieve devices associated to the events account
$devices = Device::whereIn('user_id', $account->users()->pluck('id'))->get();

if ($devices->isEmpty()) {
    return;
}

// Subscribe each token
foreach ($devices as $device) {
    $expo->subscribe('messages', $device->expo_token);
}

// Send notification
$expo->notify(['messages'], [
    'title' => "Message Received",
    'body'  => 'You have a new message',
    'data'  => json_encode(['message' => 'Expo is awesome! They are doing great work.']),
]);

Expo push tokens are persisted after every login and app load. Before we were using the ‘default’ channel name for android, (‘miscellaneous’ at one point, because we did not specify). Not sure if this is relevant?

Question: How have you determined that notifications are sent to the wrong device?
Answer: Each event will only send notifications to its accounts users. There have been several occasions where a user/device receives a notification for an account it has absolutely no association to.

Do tokens need to be unsubscribed immediately after sending?

There are still quite a few variables in this situation- in order to confirm that Expo is sending notifications to the wrong ExpoPushToken, you should collect a token from a device, send a notification to that token in particular, and confirm that the notification shows up on a different device. Otherwise, the issue could be in your server or in your app (as in, how you’re collecting tokens)

1 Like

I completely agree that our server code and how we collect expo tokens could be the culprit. But, every test we have done verifies that we are collecting/storing tokens for the correct user. the POST request that stores the expo token is aware of the authenticated user for our api. If we had an issue identifying the authenticated user, there would be many more issues on our mobile backend. Being that we are accurately identifying the authenticated user, all we do is store the expo token sent with the request and send notifications with the sketch above. We have even observed expo tokens being stored in real time, knowing which user made the request, being our app is not publicly available yet.

So are you saying the issue MUST be on our side and not on expo’s? We will continue to investigate either way.

Thanks,

1 Like

I’m definitely not saying it must be, since I can’t reproduce the issue myself I can’t give any definitive answer as to what the root cause is…I’m just suggesting you test each piece of functionality separately (and removing your server from the equation entirely is a great way to do that: if notifications work, then you know your server code is the culprit)

@charliecruzan

Thank you for your help and quick responses.

It turns out the issue WAS NOT EXPO but an undocumented behavior of the recommended PHP package from the expo docs. This package does not behave as documented/expected for apps running on multiple app servers which caused strange behavior.

I submitted a PR to the package fixing bugs and adding features, but to no avail. I have since written another well tested package in hopes it could be the recommendation for php back-ends.

The expo PR is here.

Thanks!