fcm
fcm copied to clipboard
Sending notification to the topic without FCM registration token.
Hello,
Is it possible to send a notification to topics only? Currently, when I register routeNotificationForFcm
in a Notifiable
model and return empty string, it throws an error:
{
"message": "No registration tokens provided",
"exception": "Kreait\\Firebase\\Exception\\Messaging\\InvalidArgument",
"file": "/home/forge/pashtostories.org/vendor/kreait/firebase-php/src/Firebase/Messaging/RegistrationTokens.php",
"line": 61,
No, not at this stage. Happy to review any ideas or PRs that implement this.
I had the same problem and fixed by overriding send
function in FcmChannel.php
.
public function send(mixed $notifiable, Notification $notification): ?Collection
{
// Firstly we create the message class
/** @var \NotificationChannels\Fcm\FcmMessage */
$fcmMessage = $notification->toFcm($notifiable);
// If message has a topic then send it directly
if (!is_null($fcmMessage->topic)) {
return collect(($fcmMessage->client ?? $this->client)->send($fcmMessage));
}
// Otherwise collect tokens from the notifiable model
$tokens = Arr::wrap($notifiable->routeNotificationFor('fcm', $notification));
if (empty($tokens)) {
return null;
}
return Collection::make($tokens)
->chunk(self::TOKENS_PER_REQUEST)
->map(fn ($tokens) => ($fcmMessage->client ?? $this->client)->sendMulticast($fcmMessage, $tokens->all()))
->map(fn (MulticastSendReport $report) => $this->checkReportForFailures($notifiable, $notification, $report));
}
@dwightwatson Is this behaviour correct?
I'm personally not familiar with sending notifications to topics without a token.
If it's as simple if checking if $fcmMessage->topic
exists and then sending it and ignoring any user tokens I'm fine with that. (Although, it does almost feel like an anonymous notification at that point).
Like I said above, happy to look at any PRs that introduce this behaviour.
I think we should still do sendMulticast
and check reports for failures like we do with FCM tokens as well for consistency.
Checking if $fcmMessage->topic
exists was a simple solution based on our specific use case.
We need to notify an indefinite number of users with the bare minimum load on the server.
In our APP every user has the option to subscribe/unsubscribe to a list of topics and then we send push notifications via the Topic
model using the Notifiable
trait, so it is not anonymous.
Another way to implement this could be: if routeNotificationForFcm
returns a \Kreait\Firebase\Messaging\Topic
class then we ignore tokens.
I can write a PR, just let me know how do you want to integrate it.
Would it only ever return a single \Kreait\Firebase\Messaging\Topic
or could it return a collection? Or should we use something like routeNotificationForFcmTopic
to make it distinct?
Or does it make sense to have a separate channel for this - so you use FcmChannel
for token based messages and FcmTopicChannel
for other ones? That might be the cleanest option, but would it make sense from your point of view?
A few people liked your earlier comment - perhaps they can share their 2 cents/use cases so we can work out what a good implementation would look like.