diff --git a/CHANGELOG.md b/CHANGELOG.md index e5b9b74c..4c4f86b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ Please read about the future of the Firebase Admin PHP SDK on the ## [Unreleased] +### Changed + +* The Messaging component doesn't rely on the `CloudMessage` class for message handling anymore. If you provide a + message as an array and it has an error, the Firebase API will report it. You can still use the `CloudMessage` + class as a message builder + ## [7.15.0] - 2024-09-11 ### Added diff --git a/src/Firebase/Messaging.php b/src/Firebase/Messaging.php index c1436bc7..8220338f 100644 --- a/src/Firebase/Messaging.php +++ b/src/Firebase/Messaging.php @@ -14,12 +14,12 @@ use Kreait\Firebase\Messaging\ApiClient; use Kreait\Firebase\Messaging\AppInstance; use Kreait\Firebase\Messaging\AppInstanceApiClient; -use Kreait\Firebase\Messaging\CloudMessage; use Kreait\Firebase\Messaging\Message; use Kreait\Firebase\Messaging\MessageTarget; use Kreait\Firebase\Messaging\MulticastSendReport; use Kreait\Firebase\Messaging\Processor\SetApnsContentAvailableIfNeeded; use Kreait\Firebase\Messaging\Processor\SetApnsPushTypeIfNeeded; +use Kreait\Firebase\Messaging\RawMessageFromArray; use Kreait\Firebase\Messaging\RegistrationToken; use Kreait\Firebase\Messaging\RegistrationTokens; use Kreait\Firebase\Messaging\SendReport; @@ -68,15 +68,13 @@ public function send(Message|array $message, bool $validateOnly = false): array public function sendMulticast($message, $registrationTokens, bool $validateOnly = false): MulticastSendReport { - $message = CloudMessage::fromArray( - Json::decode(Json::encode($this->makeMessage($message)), true), - ); + $message = $message instanceof Message ? $message : new RawMessageFromArray($message); $registrationTokens = RegistrationTokens::fromValue($registrationTokens); $messages = []; foreach ($registrationTokens as $registrationToken) { - $messages[] = $message->withChangedTarget(MessageTarget::TOKEN, $registrationToken->value()); + $messages[] = $this->withChangedTarget($message, MessageTarget::TOKEN, $registrationToken->value()); } return $this->sendAll($messages, $validateOnly); @@ -94,14 +92,14 @@ public function sendAll($messages, bool $validateOnly = false): MulticastSendRep $json = Json::decode((string) $response->getBody(), true); - $sendReports[$index] = SendReport::success($message->target(), $json, $message); + $sendReports[$index] = SendReport::success($this->getTarget($message), $json, $message); }, 'rejected' => function (Throwable $reason, int $index) use ($messages, &$sendReports): void { $message = $messages[$index]; $error = $this->exceptionConverter->convertException($reason); - $sendReports[$index] = SendReport::failure($message->target(), $error, $message); + $sendReports[$index] = SendReport::failure($this->getTarget($message), $error, $message); }, ]; @@ -124,7 +122,7 @@ public function validateRegistrationTokens($registrationTokenOrTokens): array { $tokens = RegistrationTokens::fromValue($registrationTokenOrTokens); - $report = $this->sendMulticast(CloudMessage::new(), $tokens, true); + $report = $this->sendMulticast(new RawMessageFromArray([]), $tokens, true); return [ 'valid' => $report->validTokens(), @@ -220,7 +218,7 @@ public function getAppInstance(RegistrationToken|string $registrationToken): App /** * @param iterable> $messages * - * @return list + * @return list */ private function ensureMessages(iterable $messages): array { @@ -238,18 +236,17 @@ private function ensureMessages(iterable $messages): array * * @throws InvalidArgumentException */ - private function makeMessage(Message|array $message): CloudMessage + private function makeMessage(Message|array $message): Message { - $message = $message instanceof Message ? $message : CloudMessage::fromArray($message); + $message = $message instanceof Message ? $message : new RawMessageFromArray($message); $message = (new SetApnsPushTypeIfNeeded())($message); - $message = (new SetApnsContentAvailableIfNeeded())($message); - return CloudMessage::fromArray(Json::decode(JSON::encode($message->jsonSerialize()), true)); + return (new SetApnsContentAvailableIfNeeded())($message); } /** - * @param iterable $messages + * @param iterable $messages * @return callable(): list */ private function createSendRequests(iterable $messages, bool $validateOnly): callable @@ -269,4 +266,42 @@ private function messageHasTarget(Message $message): bool || array_key_exists(MessageTarget::TOKEN, $check) || array_key_exists(MessageTarget::TOPIC, $check); } + + private function withChangedTarget(Message $message, string $target, string $value): Message + { + $message = Json::decode(Json::encode($message), true); + + unset( + $message[MessageTarget::CONDITION], + $message[MessageTarget::TOKEN], + $message[MessageTarget::TOPIC], + ); + + $message[$target] = $value; + + return new RawMessageFromArray($message); + } + + private function getTarget(Message $message): MessageTarget + { + $message = Json::decode(Json::encode($message), true); + + $condition = $message[MessageTarget::CONDITION] ?? null; + $token = $message[MessageTarget::TOKEN] ?? null; + $topic = $message[MessageTarget::TOPIC] ?? null; + + if (is_string($condition) && $condition !== '') { + return MessageTarget::with(MessageTarget::CONDITION, $condition); + } + + if (is_string($token) && $token !== '') { + return MessageTarget::with(MessageTarget::TOKEN, $token); + } + + if (is_string($topic) && $topic !== '') { + return MessageTarget::with(MessageTarget::TOPIC, $topic); + } + + return MessageTarget::with(MessageTarget::UNKNOWN, 'unknown'); + } } diff --git a/src/Firebase/Messaging/Processor/SetApnsContentAvailableIfNeeded.php b/src/Firebase/Messaging/Processor/SetApnsContentAvailableIfNeeded.php index 657754cc..24dbf583 100644 --- a/src/Firebase/Messaging/Processor/SetApnsContentAvailableIfNeeded.php +++ b/src/Firebase/Messaging/Processor/SetApnsContentAvailableIfNeeded.php @@ -6,10 +6,10 @@ use Beste\Json; use Kreait\Firebase\Messaging\ApnsConfig; -use Kreait\Firebase\Messaging\CloudMessage; use Kreait\Firebase\Messaging\Message; use Kreait\Firebase\Messaging\MessageData; use Kreait\Firebase\Messaging\Notification; +use Kreait\Firebase\Messaging\RawMessageFromArray; use function is_array; @@ -45,7 +45,9 @@ public function __invoke(Message $message): Message $apnsConfig = $apnsConfig->withApsField('content-available', 1); - return CloudMessage::fromArray($payload)->withApnsConfig($apnsConfig); + $payload['apns'] = $apnsConfig->toArray(); + + return new RawMessageFromArray($payload); } /** diff --git a/src/Firebase/Messaging/Processor/SetApnsPushTypeIfNeeded.php b/src/Firebase/Messaging/Processor/SetApnsPushTypeIfNeeded.php index 85450081..8229e04b 100644 --- a/src/Firebase/Messaging/Processor/SetApnsPushTypeIfNeeded.php +++ b/src/Firebase/Messaging/Processor/SetApnsPushTypeIfNeeded.php @@ -6,10 +6,10 @@ use Beste\Json; use Kreait\Firebase\Messaging\ApnsConfig; -use Kreait\Firebase\Messaging\CloudMessage; use Kreait\Firebase\Messaging\Message; use Kreait\Firebase\Messaging\MessageData; use Kreait\Firebase\Messaging\Notification; +use Kreait\Firebase\Messaging\RawMessageFromArray; use function is_array; @@ -25,6 +25,10 @@ public function __invoke(Message $message): Message { $payload = Json::decode(Json::encode($message), true); + if (!is_array($payload)) { + return $message; + } + $notification = $this->getNotification($payload); $messageData = $this->getMessageData($payload); $apnsConfig = $this->getApnsConfig($payload); @@ -46,9 +50,13 @@ public function __invoke(Message $message): Message $apnsConfig = $apnsConfig->withHeader('apns-push-type', 'alert'); } elseif ($isBackgroundMessage) { $apnsConfig = $apnsConfig->withHeader('apns-push-type', 'background'); + } else { + return $message; } - return CloudMessage::fromArray($payload)->withApnsConfig($apnsConfig); + $payload['apns'] = $apnsConfig->toArray(); + + return new RawMessageFromArray($payload); } /**