kreait / firebase-php

Unofficial Firebase Admin SDK for PHP
https://firebase-php.readthedocs.io/
MIT License
2.23k stars 427 forks source link

CloudMessage::withNotification seems to be broken #914

Closed geoidesic closed 1 month ago

geoidesic commented 1 month ago

Describe the bug

Notification::create() works but when passing that into CloudMessage->withNotification(), the result is NULL

Installed packages

beste/clock                   3.0.0   A collection of Clock implementations
beste/in-memory-cache         1.1.0   A PSR-6 In-Memory cache that can be used as a fal...
beste/json                    1.4.0   A simple JSON helper to decode and encode JSON
brick/math                    0.12.1  Arbitrary-precision arithmetic library
cboden/ratchet                v0.4.4  PHP WebSocket library
evenement/evenement           v3.0.2  Événement is a very simple event dispatching li...
ezyang/htmlpurifier           v4.17.0 Standards compliant HTML filter written in PHP
fig/http-message-util         1.1.5   Utility classes and constants for use with PSR-7 ...
firebase/php-jwt              v6.10.1 A simple library to encode and decode JSON Web To...
gocardless/gocardless-pro     4.28.0  GoCardless Pro PHP Client Library
google/auth                   v1.41.0 Google Auth Library for PHP
google/cloud-core             v1.59.0 Google Cloud PHP shared dependency, providing fun...
google/cloud-firestore        v1.44.0 Cloud Firestore Client for PHP
google/cloud-storage          v1.42.1 Cloud Storage Client for PHP
google/common-protos          v4.6.0  Google API Common Protos for PHP
google/gax                    v1.34.0 Google API Core for PHP
google/grpc-gcp               v0.4.0  gRPC GCP library for channel management
google/longrunning            0.4.3   Google LongRunning Client for PHP
google/protobuf               v4.27.2 proto library for PHP
graham-campbell/result-type   v1.1.3  An Implementation Of The Result Type
grpc/grpc                     1.57.0  gRPC library for PHP
guzzlehttp/guzzle             7.9.1   Guzzle is a PHP HTTP client library
guzzlehttp/promises           2.0.3   Guzzle promises library
guzzlehttp/psr7               2.7.0   PSR-7 message implementation that also provides c...
kreait/firebase-php           7.13.1  Firebase Admin SDK
kreait/firebase-tokens        5.1.0   A library to work with Firebase tokens
lcobucci/jwt                  5.3.0   A simple library to work with JSON Web Token and ...
maennchen/zipstream-php       3.1.0   ZipStream is a library for dynamically streaming ...
markbaker/complex             3.0.2   PHP Class for working with complex numbers
markbaker/matrix              3.0.1   PHP Class for working with matrices
monolog/monolog               3.7.0   Sends your logs to files, sockets, inboxes, datab...
mtdowling/jmespath.php        2.7.0   Declaratively specify how to extract elements fro...
phpmailer/phpmailer           v6.9.1  PHPMailer is a full-featured email creation and t...
phpoffice/phpspreadsheet      1.29.0  PHPSpreadsheet - Read, Create and Write Spreadshe...
phpoption/phpoption           1.9.3   Option Type for PHP
psr/cache                     3.0.0   Common interface for caching libraries
psr/clock                     1.0.0   Common interface for reading the clock.
psr/http-client               1.0.3   Common interface for HTTP clients
psr/http-factory              1.1.0   PSR-17: Common interfaces for PSR-7 HTTP message ...
psr/http-message              2.0     Common interface for HTTP messages
psr/log                       3.0.0   Common interface for logging libraries
psr/simple-cache              3.0.0   Common interfaces for simple caching
ralouphie/getallheaders       3.0.3   A polyfill for getallheaders.
ramsey/collection             2.0.0   A PHP library for representing and manipulating c...
ramsey/uuid                   4.7.6   A PHP library for generating and working with uni...
ratchet/rfc6455               v0.3.1  RFC6455 WebSocket protocol handler
react/cache                   v1.2.0  Async, Promise-based cache interface for ReactPHP
react/dns                     v1.13.0 Async DNS resolver for ReactPHP
react/event-loop              v1.5.0  ReactPHP's core reactor event loop that libraries...
react/promise                 v3.2.0  A lightweight implementation of CommonJS Promises...
react/socket                  v1.15.0 Async, streaming plaintext TCP/IP and secure TLS ...
react/stream                  v1.4.0  Event-driven readable and writable streams for no...
rize/uri-template             0.3.6   PHP URI Template (RFC 6570) supports both expansi...
symfony/deprecation-contracts v3.5.0  A generic function and convention to trigger depr...
symfony/http-foundation       v6.4.8  Defines an object-oriented layer for the HTTP spe...
symfony/polyfill-ctype        v1.30.0 Symfony polyfill for ctype functions
symfony/polyfill-mbstring     v1.30.0 Symfony polyfill for the Mbstring extension
symfony/polyfill-php80        v1.30.0 Symfony polyfill backporting some PHP 8.0+ featur...
symfony/polyfill-php83        v1.30.0 Symfony polyfill backporting some PHP 8.3+ featur...
symfony/routing               v6.4.8  Maps an HTTP request to a set of configuration va...
vlucas/phpdotenv              v5.6.1  Loads environment variables from `.env` to `geten...

PHP version and extensions

composer                2.6.6    Composer package
composer-plugin-api     2.6.0    The Composer Plugin API
composer-runtime-api    2.2.2    The Composer Runtime API
ext-apcu                5.1.23   The apcu PHP extension
ext-bcmath              8.3.8    The bcmath PHP extension
ext-bz2                 8.3.8    The bz2 PHP extension
ext-calendar            8.3.8    The calendar PHP extension
ext-ctype               8.3.8    The ctype PHP extension
ext-curl                8.3.8    The curl PHP extension
ext-date                8.3.8    The date PHP extension
ext-dom                 20031129 The dom PHP extension
ext-exif                8.3.8    The exif PHP extension
ext-fileinfo            8.3.8    The fileinfo PHP extension
ext-filter              8.3.8    The filter PHP extension
ext-ftp                 8.3.8    The ftp PHP extension
ext-gd                  8.3.8    The gd PHP extension
ext-gettext             8.3.8    The gettext PHP extension
ext-grpc                1.65.1   The grpc PHP extension
ext-hash                8.3.8    The hash PHP extension
ext-iconv               8.3.8    The iconv PHP extension
ext-igbinary            3.2.15   The igbinary PHP extension
ext-imagick             3.7.0    The imagick PHP extension
ext-imap                8.3.8    The imap PHP extension
ext-intl                8.3.8    The intl PHP extension
ext-json                8.3.8    The json PHP extension
ext-libxml              8.3.8    The libxml PHP extension
ext-mbstring            8.3.8    The mbstring PHP extension
ext-memcache            8.2      The memcache PHP extension
ext-memcached           3.2.0    The memcached PHP extension
ext-msgpack             2.2.0    The msgpack PHP extension
ext-mysqli              8.3.8    The mysqli PHP extension
ext-mysqlnd             0        The mysqlnd PHP extension (actual version: mysqlnd 8.3.8)
ext-openssl             8.3.8    The openssl PHP extension
ext-pcntl               8.3.8    The pcntl PHP extension
ext-pcre                8.3.8    The pcre PHP extension
ext-pdo                 8.3.8    The PDO PHP extension
ext-pdo_mysql           8.3.8    The pdo_mysql PHP extension
ext-pdo_sqlite          8.3.8    The pdo_sqlite PHP extension
ext-phar                8.3.8    The Phar PHP extension
ext-random              8.3.8    The random PHP extension
ext-readline            8.3.8    The readline PHP extension
ext-redis               6.0.2    The redis PHP extension
ext-reflection          8.3.8    The Reflection PHP extension
ext-session             8.3.8    The session PHP extension
ext-simplexml           8.3.8    The SimpleXML PHP extension
ext-sockets             8.3.8    The sockets PHP extension
ext-sodium              8.3.8    The sodium PHP extension
ext-spl                 8.3.8    The SPL PHP extension
ext-sqlite3             8.3.8    The sqlite3 PHP extension
ext-tokenizer           8.3.8    The tokenizer PHP extension
ext-xml                 8.3.8    The xml PHP extension
ext-xmlreader           8.3.8    The xmlreader PHP extension
ext-xmlrpc              1.0.0RC3 The xmlrpc PHP extension
ext-xmlwriter           8.3.8    The xmlwriter PHP extension
ext-xsl                 8.3.8    The xsl PHP extension
ext-zend-opcache        8.3.8    The Zend OPcache PHP extension
ext-zip                 1.22.3   The zip PHP extension
ext-zlib                8.3.8    The zlib PHP extension
lib-bz2                 1.0.8    The bz2 library
lib-curl                7.76.1   The curl library
lib-curl-libssh         0.10.4   curl libssh version
lib-curl-openssl        3.0.7    curl OpenSSL version (3.0.7)
lib-curl-zlib           1.2.11   curl zlib version
lib-date-timelib        2022.10  date timelib version
lib-fileinfo-libmagic   543      fileinfo libmagic version
lib-gd                  2.3.3    The gd library
lib-iconv               2.34     The iconv library
lib-icu                 73.2     The ICU unicode and globalization support library
lib-icu-cldr            43.1     ICU CLDR project version
lib-icu-unicode         15.0.0   ICU unicode version
lib-icu-zoneinfo        2023.3   zoneinfo ("Olson") database for icu
lib-imagick-imagemagick 7.1.1.33 The imagick-imagemagick library
lib-libsodium           1.0.18   The libsodium library
lib-libxml              2.9.13   libxml library version
lib-libxslt             1.1.34   The libxslt library
lib-libxslt-libxml      2.9.13   libxml version libxslt is compiled against
lib-mbstring-libmbfl    1.3.2    mbstring libmbfl version
lib-mbstring-oniguruma  6.9.9    mbstring oniguruma version
lib-openssl             3.0.7    OpenSSL 3.0.7 1 Nov 2022
lib-pcre                10.40    The pcre library
lib-pcre-unicode        14.0.0   PCRE Unicode version support
lib-pdo_sqlite-sqlite   3.34.1   The pdo_sqlite-sqlite library
lib-sqlite3-sqlite      3.34.1   The sqlite3-sqlite library
lib-zip-libzip          1.10.1   The zip-libzip library
lib-zlib                1.2.11   The zlib library
php                     8.3.8    The PHP interpreter
php-64bit               8.3.8    The PHP interpreter, 64bit
php-ipv6                8.3.8    The PHP interpreter, with IPv6 support

Steps to reproduce the issue.

<?php
// die('prevent abuse');
require_once(dirname(__DIR__).'/support/vendor/autoload.php');

error_reporting(E_ALL);
ini_set('display_errors', 'yes');

use Kreait\Firebase\Factory;
use Kreait\Firebase\Messaging\CloudMessage;
use Kreait\Firebase\Messaging\Notification;
use Kreait\Firebase\Messaging\MessageTarget;

$token = 'redacted';

$serviceAccount = '{
... redacted
}';

echo '<pre>';
try {
  $factory = (new Factory)
      ->withServiceAccount($serviceAccount)
      // ->withDatabaseUri('https://my-project-default-rtdb.firebaseio.com')
    ;

  $auth = $factory->createAuth();
  $realtimeDatabase = $factory->createDatabase();
  $cloudMessaging = $factory->createMessaging();
  $remoteConfig = $factory->createRemoteConfig();
  $cloudStorage = $factory->createStorage();
  $firestore = $factory->createFirestore();

  $notification = Notification::create('Hello', 'World');

  var_dump($notification);

/* 
  shows the following:

  object(Kreait\Firebase\Messaging\Notification)#850 (3) {
    ["title":"Kreait\Firebase\Messaging\Notification":private]=>
    string(5) "Hello"
    ["body":"Kreait\Firebase\Messaging\Notification":private]=>
    string(5) "World"
    ["imageUrl":"Kreait\Firebase\Messaging\Notification":private]=>
    NULL
  }
*/

  // Create a CloudMessage instance
  $message = CloudMessage::new()
      ->withNotification($notification)
      ->withData([
        'story_id' => 'story_1234'
      ])
      ->withTarget(MessageTarget::TOKEN, $token); // Replace with actual device registration token

  var_dump($message);
/* 
  shows the following:

  object(Kreait\Firebase\Messaging\CloudMessage)#853 (7) {
    ["data":"Kreait\Firebase\Messaging\CloudMessage":private]=>
    object(Kreait\Firebase\Messaging\MessageData)#838 (1) {
      ["data":"Kreait\Firebase\Messaging\MessageData":private]=>
      array(0) {
      }
    }
    ["notification":"Kreait\Firebase\Messaging\CloudMessage":private]=>
    object(Kreait\Firebase\Messaging\Notification)#845 (3) {
      ["title":"Kreait\Firebase\Messaging\Notification":private]=>
      NULL
      ["body":"Kreait\Firebase\Messaging\Notification":private]=>
      NULL
      ["imageUrl":"Kreait\Firebase\Messaging\Notification":private]=>
      NULL
    }
    ... etc.
  }
*/

  // Send the message
  $response = $cloudMessaging->send($message);
  echo "Message sent successfully:";
  var_dump($response);

} catch (Exception $e) {
  echo "Error: " . $e->getMessage();
}

Error message/Stack trace

object(Kreait\Firebase\Messaging\Notification)#850 (3) {
  ["title":"Kreait\Firebase\Messaging\Notification":private]=>
  string(5) "Hello"
  ["body":"Kreait\Firebase\Messaging\Notification":private]=>
  string(5) "World"
  ["imageUrl":"Kreait\Firebase\Messaging\Notification":private]=>
  NULL
}
object(Kreait\Firebase\Messaging\CloudMessage)#853 (7) {
  ["data":"Kreait\Firebase\Messaging\CloudMessage":private]=>
  object(Kreait\Firebase\Messaging\MessageData)#838 (1) {
    ["data":"Kreait\Firebase\Messaging\MessageData":private]=>
    array(0) {
    }
  }
  ["notification":"Kreait\Firebase\Messaging\CloudMessage":private]=>
  object(Kreait\Firebase\Messaging\Notification)#845 (3) {
    ["title":"Kreait\Firebase\Messaging\Notification":private]=>
    NULL
    ["body":"Kreait\Firebase\Messaging\Notification":private]=>
    NULL
    ["imageUrl":"Kreait\Firebase\Messaging\Notification":private]=>
    NULL
  }
  ["androidConfig":"Kreait\Firebase\Messaging\CloudMessage":private]=>
  object(Kreait\Firebase\Messaging\AndroidConfig)#843 (1) {
    ["config":"Kreait\Firebase\Messaging\AndroidConfig":private]=>
    array(0) {
    }
  }
  ["apnsConfig":"Kreait\Firebase\Messaging\CloudMessage":private]=>
  object(Kreait\Firebase\Messaging\ApnsConfig)#844 (3) {
    ["headers":"Kreait\Firebase\Messaging\ApnsConfig":private]=>
    array(0) {
    }
    ["payload":"Kreait\Firebase\Messaging\ApnsConfig":private]=>
    array(0) {
    }
    ["fcmOptions":"Kreait\Firebase\Messaging\ApnsConfig":private]=>
    array(0) {
    }
  }
  ["webPushConfig":"Kreait\Firebase\Messaging\CloudMessage":private]=>
  object(Kreait\Firebase\Messaging\WebPushConfig)#842 (1) {
    ["config":"Kreait\Firebase\Messaging\WebPushConfig":private]=>
    array(0) {
    }
  }
  ["fcmOptions":"Kreait\Firebase\Messaging\CloudMessage":private]=>
  object(Kreait\Firebase\Messaging\FcmOptions)#830 (1) {
    ["data":"Kreait\Firebase\Messaging\FcmOptions":private]=>
    array(0) {
    }
  }
  ["target":"Kreait\Firebase\Messaging\CloudMessage":private]=>
  object(Kreait\Firebase\Messaging\MessageTarget)#837 (2) {
    ["type":"Kreait\Firebase\Messaging\MessageTarget":private]=>
    string(5) "token"
    ["value":"Kreait\Firebase\Messaging\MessageTarget":private]=>
    string(163) "redacted"
  }
}
Message sent successfully:array(1) {
  ["name"]=>
  string(67) "redacted"
}


### Additional information

_No response_
jeromegamez commented 1 month ago

CloudMessage::withTarget() is a static constructor and meant to be used to instantiate a new message with a target as starting point. You should use the withChangedTarget() method.

$message = CloudMessage::new()
    ->withNotification($notification)
    ->withData(['story_id' => 'story_1234'])
    ->withChangedTarget(MessageTarget::TOKEN, $token);

// or

$message = CloudMessage::withTarget(MessageTarget::TOKEN, $token)
    ->withNotification($notification)
    ->withData(['story_id' => 'story_1234']);

The method names are not the best, but that's the price for backward compatibility 😅