Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update documentation with publish_multiple example #61

Open
samuel-andres opened this issue Oct 27, 2023 · 4 comments
Open

Update documentation with publish_multiple example #61

samuel-andres opened this issue Oct 27, 2023 · 4 comments

Comments

@samuel-andres
Copy link

The README.md is pretty clear on how to handle the errors when sending a single push notification, however, most of the times we will be sending the same push notification to a bunch of devices, so in that case, I think it would be greatly valuable an example of how to handle that case.

@sergioisidoro
Copy link

sergioisidoro commented Mar 30, 2024

Here's something if anyone wants to take use of.

I think the trick here to match push tickets to tokens is to keep a parallel list of the same order, since the docs mention:

data will contain an array of push tickets in the same order in which the messages were sent

def push_expo_notifications(user, title, body):
    messages = []
    token_ids = []

    for device in user.devices.filter(active=True):
        messages.append(
            PushMessage(
                to=device.expo_token,
                title=title,
                body=body
            )
        )
        token_ids.append(device.id)

    try:
        responses = PushClient().publish_multiple(messages)
    except PushServerError as exc:
        # Encountered some likely formatting/validation error.
        raise
    except (ConnectionError) as exc:
        # Encountered some Connection or HTTP error.
        raise
    
    for index, response in enumerate(responses):
        try:
          response.validate_response()
        except DeviceNotRegisteredError:
            # Mark the push token as inactive
            UserDevice.objects.filter(id=token_ids[index]).update(active=False)
            # Or use the token from push_message - NOTE that `to` field may be a list of recipients according to the API
            UserDevice.objects.filter(expo_token=response.push_message.to).update(active=False)
        except PushTicketError as exc:
            # Encountered some other per-notification error.
            raise

@YPCrumble
Copy link

@sergioisidoro doesn't this just use the order to get the device token? Isn't the device token already present in each response via response.push_message.to?

@sergioisidoro
Copy link

sergioisidoro commented Apr 4, 2024

I think you're right. I checked that publish returned push tickets, and completely missed that the push ticket already contained push_message in the named tuple.

Ironically, it uses the exact same method I'm using here, using the index of the response to match the push message to the push receipt 😅

for i, push_ticket in enumerate(response_data['data']):
push_tickets.append(
PushTicket(
push_message=push_messages[i],

I'll update the example, and my own code. Thanks @YPCrumble !

Just an important caveat, that with the PRs that enable multiple senders, the to field might be a list of recipients:

[
  {
    "to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
    "sound": "default",
    "body": "Hello world!"
  },
  {
    "to": "ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]",
    "badge": 1,
    "body": "You've got mail"
  },
  {
    "to": [
      "ExponentPushToken[zzzzzzzzzzzzzzzzzzzzzz]",
      "ExponentPushToken[aaaaaaaaaaaaaaaaaaaaaa]"
    ],
    "body": "Breaking news!"
  }
]

@YPCrumble
Copy link

I think your insight that the responses are in the same order is what I needed for my use case. If I publish ten notifications, and only one fails for whatever reason, I want to retry that ticket only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants