Service Account Mapping Fails with Valinor in kreait/firebase-php 7.24.0
Describe the bug
After upgrading from kreait/firebase-php 7.18.0 to 7.24.0, Firebase service account credentials fail to load when passed as file paths to Factory::withServiceAccount(), or the files content as array.
The Valinor mapper throws a type mapping error indicating it cannot convert snake_case keys to camelCase properties.
Installed packages
beste/clock 3.0.0 A collection of Clock implementations
beste/in-memory-cache 1.4.0 A PSR-6 In-Memory cache that can be used as a fallback implementation and/or in tests.
beste/json 1.7.0 A simple JSON helper to decode and encode JSON
brick/math 0.14.1 Arbitrary-precision arithmetic library
carbonphp/carbon-doctrine-types 3.2.0 Types to use Carbon in Doctrine
clue/ndjson-react 1.3.0 Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.
clue/stream-filter 1.7.0 A simple and modern approach to stream filtering in PHP
composer/pcre 3.3.2 PCRE wrapping library that offers type-safe preg_* replacements.
composer/semver 3.4.4 Semver library that offers utilities, version constraint parsing and validation.
composer/xdebug-handler 3.0.5 Restarts a process without Xdebug.
cuyz/valinor 2.3.1 Library that helps to map any input into a strongly-typed value object structure.
dflydev/dot-access-data 3.0.3 Given a deep data structure, access data by dot notation.
doctrine/dbal 4.4.1 Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.
doctrine/deprecations 1.1.5 A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.
doctrine/inflector 2.1.0 PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.
doctrine/lexer 3.0.1 PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.
dragonmantank/cron-expression 3.6.0 CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due
driftingly/rector-laravel 2.1.6 Rector upgrades rules for Laravel Framework
egulias/email-validator 4.0.4 A library for validating emails against several RFCs
elastic/transport 8.11.0 HTTP transport PHP library for Elastic products
elasticsearch/elasticsearch 8.19.0 PHP Client for Elasticsearch
evenement/evenement 3.0.2 รvรฉnement is a very simple event dispatching library for PHP
fakerphp/faker 1.24.1 Faker is a PHP library that generates fake data for you.
fidry/cpu-core-counter 1.3.0 Tiny utility to get the number of CPU cores.
fig/http-message-util 1.1.5 Utility classes and constants for use with PSR-7 (psr/http-message)
filp/whoops 2.18.4 php error handling for cool kids
firebase/php-jwt 6.11.1 A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.
fossbarrow/laravel-phpcs dev-main 5dbf058 phpcs ruleset for laravel projects
friendsofphp/php-cs-fixer 3.91.3 A tool to automatically fix PHP code style
fruitcake/php-cors 1.4.0 Cross-origin resource sharing library for the Symfony HttpFoundation
google/analytics-data 0.22.3 Google Analytics Data Client for PHP
google/apiclient 2.18.4 Client library for Google APIs
google/apiclient-services 0.423.0 Client library for Google APIs
google/auth 1.49.0 Google Auth Library for PHP
google/cloud-bigquery 1.34.6 BigQuery Client for PHP
google/cloud-core 1.69.0 Google Cloud PHP shared dependency, providing functionality useful to all components.
google/cloud-pubsub 1.51.0 Cloud PubSub Client for PHP
google/cloud-storage 1.49.0 Cloud Storage Client for PHP
google/common-protos 4.12.4 Google API Common Protos for PHP
google/gax 1.40.0 Google API Core for PHP
google/grpc-gcp 0.4.1 gRPC GCP library for channel management
google/longrunning 0.6.0 Google LongRunning Client for PHP
google/protobuf 4.33.2 proto library for PHP
googleads/google-ads-php 26.2.0 Google Ads API client for PHP
graham-campbell/result-type 1.1.3 An Implementation Of The Result Type
grpc/grpc 1.74.0 gRPC library for PHP
guzzlehttp/guzzle 7.10.0 Guzzle is a PHP HTTP client library
guzzlehttp/promises 2.3.0 Guzzle promises library
guzzlehttp/psr7 2.8.0 PSR-7 message implementation that also provides common utility methods
guzzlehttp/uri-template 1.0.5 A polyfill class for uri_template of PHP
hamcrest/hamcrest-php 2.1.1 This is the PHP port of Hamcrest Matchers
iamcal/sql-parser 0.6 MySQL schema parser
imdhemy/google-play-billing 1.11.0 Google Play Billing
intervention/gif 4.2.2 Native PHP GIF Encoder/Decoder
intervention/image 3.11.5 PHP Image Processing
kamerk22/amazongiftcode 1.0.6 Laravel Package for Amazon Gift Codes.
kreait/firebase-php 7.24.0 Firebase Admin SDK
kreait/firebase-tokens 5.3.0 A library to work with Firebase tokens
kreait/laravel-firebase 6.2.0 A Laravel package for the Firebase PHP Admin SDK
larastan/larastan 3.8.0 Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel
laravel/framework 12.42.0 The Laravel Framework.
laravel/prompts 0.3.8 Add beautiful and user-friendly forms to your command-line applications.
laravel/sail 1.51.0 Docker files for running a basic Laravel application.
laravel/serializable-closure 2.0.7 Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.
laravel/tinker 2.10.2 Powerful REPL for the Laravel framework.
lcobucci/jwt 5.6.0 A simple library to work with JSON Web Token and JSON Web Signature
league/commonmark 2.8.0 Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)
league/config 1.2.0 Define configuration arrays with strict schemas and access values with dot notation
league/flysystem 3.30.2 File storage abstraction for PHP
league/flysystem-local 3.30.2 Local filesystem adapter for Flysystem.
league/mime-type-detection 1.16.0 Mime-type detection for Flysystem
league/uri 7.7.0 URI manipulation library
league/uri-interfaces 7.7.0 Common tools for parsing and resolving RFC3987/RFC3986 URI
level23/druid-client 4.1.2 Druid php client for executing queries and more
mervick/aes-everywhere 1.1.3 Aes Everywhere - Cross Language Encryption Library (AES/256/CBC/PKCS5)
mockery/mockery 1.6.12 Mockery is a simple yet flexible PHP mock object framework
monolog/monolog 3.9.0 Sends your logs to files, sockets, inboxes, databases and various web services
mtdowling/jmespath.php 2.8.0 Declaratively specify how to extract elements from a JSON document
myclabs/deep-copy 1.13.4 Create deep copies (clones) of your objects
nesbot/carbon 3.11.0 An API extension for DateTime that supports 281 different languages.
nette/schema 1.3.3 ๐ Nette Schema: validating data structures against a given Schema.
nette/utils 4.1.0 ๐ Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.
nikic/php-parser 5.7.0 A PHP parser written in PHP
nunomaduro/collision 8.8.3 Cli error handling for console/command-line PHP applications.
nunomaduro/termwind 2.3.3 Its like Tailwind CSS, but for the console.
open-telemetry/api 1.7.1 API for OpenTelemetry PHP.
open-telemetry/context 1.4.0 Context implementation for OpenTelemetry PHP.
openai-php/client 0.10.3 OpenAI PHP is a supercharged PHP API client that allows you to interact with the Open AI API
paragonie/constant_time_encoding 3.1.3 Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)
paragonie/random_compat 9.99.100 PHP 5.x polyfill for random_bytes() and random_int() from PHP 7
pda/pheanstalk 5.1.0 PHP client for beanstalkd queue
pdepend/pdepend 2.16.2 Official version of pdepend to be handled with Composer
phar-io/manifest 2.0.4 Component for reading phar.io manifest information from a PHP Archive (PHAR)
phar-io/version 3.2.1 Library for handling version information and constraints
php-http/curl-client 2.4.0 PSR-18 and HTTPlug Async client with cURL
php-http/discovery 1.20.0 Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations
php-http/httplug 2.4.1 HTTPlug, the HTTP client abstraction for PHP
php-http/message 1.16.2 HTTP Message related tools
php-http/multipart-stream-builder 1.4.2 A builder class that help you create a multipart stream
php-http/promise 1.3.1 Promise used for asynchronous HTTP requests
phpmd/phpmd 2.15.0 PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.
phpoption/phpoption 1.9.4 Option Type for PHP
phpseclib/phpseclib 3.0.47 PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.
phpstan/phpstan 2.1.33 PHPStan - PHP Static Analysis Tool
phpstan/phpstan-mockery 2.0.0 PHPStan Mockery extension
phpunit/php-code-coverage 11.0.11 Library that provides collection, processing, and rendering functionality for PHP code coverage information.
phpunit/php-file-iterator 5.1.0 FilterIterator implementation that filters files based on a list of suffixes.
phpunit/php-invoker 5.0.1 Invoke callables with a timeout
phpunit/php-text-template 4.0.1 Simple template engine.
phpunit/php-timer 7.0.1 Utility class for timing
phpunit/phpunit 11.5.46 The PHP Unit Testing framework.
psr/cache 3.0.0 Common interface for caching libraries
psr/clock 1.0.0 Common interface for reading the clock.
psr/container 2.0.2 Common Container Interface (PHP FIG PSR-11)
psr/event-dispatcher 1.0.0 Standard interfaces for event handling.
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 factories
psr/http-message 2.0 Common interface for HTTP messages
psr/log 3.0.2 Common interface for logging libraries
psr/simple-cache 3.0.0 Common interfaces for simple caching
psy/psysh 0.12.16 An interactive shell for modern PHP.
ralouphie/getallheaders 3.0.3 A polyfill for getallheaders.
ramsey/collection 2.1.1 A PHP library for representing and manipulating collections.
ramsey/uuid 4.9.1 A PHP library for generating and working with universally unique identifiers (UUIDs).
react/cache 1.2.0 Async, Promise-based cache interface for ReactPHP
react/child-process 0.6.6 Event-driven library for executing child processes with ReactPHP.
react/dns 1.14.0 Async DNS resolver for ReactPHP
react/event-loop 1.6.0 ReactPHP's core reactor event loop that libraries can use for evented I/O.
react/promise 3.3.0 A lightweight implementation of CommonJS Promises/A for PHP
react/socket 1.17.0 Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP
react/stream 1.4.0 Event-driven readable and writable streams for non-blocking I/O in ReactPHP
rector/rector 2.2.14 Instant Upgrade and Automated Refactoring of any PHP code
rize/uri-template 0.4.1 PHP URI Template (RFC 6570) supports both expansion & extraction
sebastian/cli-parser 3.0.2 Library for parsing CLI options
sebastian/code-unit 3.0.3 Collection of value objects that represent the PHP code units
sebastian/code-unit-reverse-lookup 4.0.1 Looks up which function or method a line of code belongs to
sebastian/comparator 6.3.2 Provides the functionality to compare PHP values for equality
sebastian/complexity 4.0.1 Library for calculating the complexity of PHP code units
sebastian/diff 6.0.2 Diff implementation
sebastian/environment 7.2.1 Provides functionality to handle HHVM/PHP environments
sebastian/exporter 6.3.2 Provides the functionality to export PHP variables for visualization
sebastian/global-state 7.0.2 Snapshotting of global state
sebastian/lines-of-code 3.0.1 Library for counting the lines of code in PHP source code
sebastian/object-enumerator 6.0.1 Traverses array structures and object graphs to enumerate all referenced objects
sebastian/object-reflector 4.0.1 Allows reflection of object attributes, including inherited and non-public ones
sebastian/recursion-context 6.0.3 Provides functionality to recursively process PHP variables
sebastian/type 5.1.3 Collection of value objects that represent the types of the PHP type system
sebastian/version 5.0.2 Library that helps with managing the version number of Git-hosted PHP projects
spatie/backtrace 1.8.1 A better backtrace
spatie/error-solutions 1.1.3 This is my package error-solutions
spatie/flare-client-php 1.10.1 Send PHP errors to Flare
spatie/ignition 1.15.1 A beautiful error page for PHP applications.
spatie/laravel-ignition 2.9.1 A beautiful error page for Laravel applications.
squizlabs/php_codesniffer 3.13.5 PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.
staabm/side-effects-detector 1.0.5 A static analysis tool to detect side effects in PHP code
symfony/cache 7.4.1 Provides extended PSR-6, PSR-16 (and tags) implementations
symfony/cache-contracts 3.6.0 Generic abstractions related to caching
symfony/clock 8.0.0 Decouples applications from the system clock
symfony/config 7.4.1 Helps you find, load, combine, autofill and validate configuration values of any kind
symfony/console 7.4.1 Eases the creation of beautiful and testable command line interfaces
symfony/css-selector 7.4.0 Converts CSS selectors to XPath expressions
symfony/dependency-injection 7.4.2 Allows you to standardize and centralize the way objects are constructed in your application
symfony/deprecation-contracts 3.6.0 A generic function and convention to trigger deprecation notices
symfony/dotenv 7.4.0 Registers environment variables from a .env file
symfony/error-handler 7.4.0 Provides tools to manage errors and ease debugging PHP code
symfony/event-dispatcher 8.0.0 Provides tools that allow your application components to communicate with each other by dispatching events and listening to them
symfony/event-dispatcher-contracts 3.6.0 Generic abstractions related to dispatching event
symfony/filesystem 7.4.0 Provides basic utilities for the filesystem
symfony/finder 7.4.0 Finds files and directories via an intuitive fluent interface
symfony/http-foundation 7.4.1 Defines an object-oriented layer for the HTTP specification
symfony/http-kernel 7.4.2 Provides a structured process for converting a Request into a Response
symfony/mailer 7.4.0 Helps sending emails
symfony/mime 7.4.0 Allows manipulating MIME messages
symfony/options-resolver 8.0.0 Provides an improved replacement for the array_replace PHP function
symfony/polyfill-ctype 1.33.0 Symfony polyfill for ctype functions
symfony/polyfill-intl-grapheme 1.33.0 Symfony polyfill for intl's grapheme_* functions
symfony/polyfill-intl-idn 1.33.0 Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions
symfony/polyfill-intl-normalizer 1.33.0 Symfony polyfill for intl's Normalizer class and related functions
symfony/polyfill-mbstring 1.33.0 Symfony polyfill for the Mbstring extension
symfony/polyfill-php80 1.33.0 Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions
symfony/polyfill-php81 1.33.0 Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions
symfony/polyfill-php82 1.33.0 Symfony polyfill backporting some PHP 8.2+ features to lower PHP versions
symfony/polyfill-php83 1.33.0 Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions
symfony/polyfill-php84 1.33.0 Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions
symfony/polyfill-php85 1.33.0 Symfony polyfill backporting some PHP 8.5+ features to lower PHP versions
symfony/polyfill-uuid 1.33.0 Symfony polyfill for uuid functions
symfony/process 7.4.0 Executes commands in sub-processes
symfony/property-access 7.4.0 Provides functions to read and write from/to an object or array using a simple string notation
symfony/property-info 8.0.1 Extracts information about PHP class' properties using metadata of popular sources
symfony/routing 7.4.0 Maps an HTTP request to a set of configuration variables
symfony/serializer 7.4.2 Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.
symfony/service-contracts 3.6.1 Generic abstractions related to writing services
symfony/stopwatch 8.0.0 Provides a way to profile code
symfony/string 8.0.1 Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way
symfony/translation 8.0.1 Provides tools to internationalize your application
symfony/translation-contracts 3.6.1 Generic abstractions related to translation
symfony/type-info 8.0.1 Extracts PHP types information.
symfony/uid 7.4.0 Provides an object-oriented API to generate and represent UIDs
symfony/var-dumper 7.4.0 Provides mechanisms for walking through any arbitrary PHP variable
symfony/var-exporter 8.0.0 Allows exporting any serializable PHP data structure to plain PHP code
symfony/yaml 7.4.1 Loads and dumps YAML files
tailflow/laravel-orion 2.23.0 Orion for Laravel allows you to build a fully featured REST API based on your Eloquent models and relationships with the simplicity of Laravel as you love it.
theseer/tokenizer 1.3.1 A small library for converting tokenized PHP source code into XML and potentially other formats
tijsverkoyen/css-to-inline-styles 2.3.0 CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.
vectorface/mysqlite 0.1.7 Select MySQL compatibility functions for PDO's SQLite driver
vlucas/phpdotenv 5.6.2 Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.
voku/portable-ascii 2.0.3 Portable ASCII library - performance optimized (ascii) string functions for php.
webmozart/assert 1.12.1 Assertions to validate method input/output with nice error messages.
PHP version and extensions
composer 2.8.11 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.27 The apcu PHP extension
ext-bcmath 8.4.15 The bcmath PHP extension
ext-calendar 8.4.15 The calendar PHP extension
ext-ctype 8.4.15 The ctype PHP extension
ext-curl 8.4.15 The curl PHP extension
ext-date 8.4.15 The date PHP extension
ext-dom 20031129 The dom PHP extension
ext-exif 8.4.15 The exif PHP extension
ext-ffi 8.4.15 The FFI PHP extension
ext-fileinfo 8.4.15 The fileinfo PHP extension
ext-filter 8.4.15 The filter PHP extension
ext-ftp 8.4.15 The ftp PHP extension
ext-gd 8.4.15 The gd PHP extension
ext-gettext 8.4.15 The gettext PHP extension
ext-hash 8.4.15 The hash PHP extension
ext-iconv 8.4.15 The iconv PHP extension
ext-igbinary 3.2.16 The igbinary PHP extension
ext-imap 1.0.3 The imap PHP extension
ext-intl 8.4.15 The intl PHP extension
ext-json 8.4.15 The json PHP extension
ext-libxml 8.4.15 The libxml PHP extension
ext-mbstring 8.4.15 The mbstring PHP extension
ext-mysqli 8.4.15 The mysqli PHP extension
ext-mysqlnd 0 The mysqlnd PHP extension (actual version: mysqlnd 8.4.15)
ext-openssl 8.4.15 The openssl PHP extension
ext-pcntl 8.4.15 The pcntl PHP extension
ext-pcre 8.4.15 The pcre PHP extension
ext-pdo 8.4.15 The PDO PHP extension
ext-pdo_mysql 8.4.15 The pdo_mysql PHP extension
ext-pdo_pgsql 8.4.15 The pdo_pgsql PHP extension
ext-pdo_sqlite 8.4.15 The pdo_sqlite PHP extension
ext-pgsql 8.4.15 The pgsql PHP extension
ext-phar 8.4.15 The Phar PHP extension
ext-posix 8.4.15 The posix PHP extension
ext-random 8.4.15 The random PHP extension
ext-rdkafka 6.0.5 The rdkafka PHP extension
ext-readline 8.4.15 The readline PHP extension
ext-redis 6.3.0 The redis PHP extension
ext-reflection 8.4.15 The Reflection PHP extension
ext-session 8.4.15 The session PHP extension
ext-shmop 8.4.15 The shmop PHP extension
ext-simplexml 8.4.15 The SimpleXML PHP extension
ext-soap 8.4.15 The soap PHP extension
ext-sockets 8.4.15 The sockets PHP extension
ext-sodium 8.4.15 The sodium PHP extension
ext-spl 8.4.15 The SPL PHP extension
ext-sqlite3 8.4.15 The sqlite3 PHP extension
ext-sysvmsg 8.4.15 The sysvmsg PHP extension
ext-sysvsem 8.4.15 The sysvsem PHP extension
ext-sysvshm 8.4.15 The sysvshm PHP extension
ext-tokenizer 8.4.15 The tokenizer PHP extension
ext-xml 8.4.15 The xml PHP extension
ext-xmlreader 8.4.15 The xmlreader PHP extension
ext-xmlwriter 8.4.15 The xmlwriter PHP extension
ext-xsl 8.4.15 The xsl PHP extension
ext-zend-opcache 8.4.15 The Zend OPcache PHP extension
ext-zip 1.22.7 The zip PHP extension
ext-zlib 8.4.15 The zlib PHP extension
lib-curl 8.5.0 The curl library
lib-curl-libssh 0.10.6 curl libssh version
lib-curl-openssl 3.0.13 curl OpenSSL version (3.0.13)
lib-curl-zlib 1.3 curl zlib version
lib-date-timelib 2022.14 date timelib version
lib-date-zoneinfo 0 zoneinfo ("Olson") database for date
lib-fileinfo-libmagic 545 fileinfo libmagic version
lib-gd 2.3.3 The gd library
lib-iconv 2.39 The iconv library
lib-icu 74.2 The ICU unicode and globalization support library
lib-icu-cldr 44.1 ICU CLDR project version
lib-icu-unicode 15.1.0 ICU unicode version
lib-icu-zoneinfo 2023.3 zoneinfo ("Olson") database for icu
lib-libsodium 1.0.18 The libsodium library
lib-libxml 2.9.14 libxml library version
lib-libxslt 1.1.39 The libxslt library
lib-libxslt-libxml 2.9.14 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.13 OpenSSL 3.0.13 30 Jan 2024
lib-pcre 10.42 The pcre library
lib-pcre-unicode 14.0.0 PCRE Unicode version support
lib-pdo_pgsql-libpq 16.10 libpq for pdo_pgsql
lib-pdo_sqlite-sqlite 3.45.1 The pdo_sqlite-sqlite library
lib-pgsql-libpq 16.10 libpq for pgsql
lib-rdkafka-librdkafka 2.3.0 librdkafka for rdkafka
lib-sqlite3-sqlite 3.45.1 The sqlite3-sqlite library
lib-zip-libzip 1.7.3 The zip-libzip library
lib-zlib 1.3 The zlib library
php 8.4.15 The PHP interpreter
php-64bit 8.4.15 The PHP interpreter, 64bit
php-ipv6 8.4.15 The PHP interpreter, with IPv6 support
Steps to reproduce the issue.
- Create a standard Google service account JSON file (downloaded from Firebase Console)
- Pass the file path to Factory::withServiceAccount($pathToJsonFile)
- Call createMessaging() or any other factory method
- Observe the Valinor mapping error
$credentials = '/path/to/service-account.json';
$factory = new \Kreait\Firebase\Factory();
$messaging = $factory
->withServiceAccount($credentials) // Fails here
->withProjectId('my-project')
->createMessaging();
Error message/Stack trace
CuyZ\Valinor\Mapper\TypeTreeMapperError: Could not map type `Kreait\Firebase\ServiceAccount` with value iterable{auth_provider_x509_cert_url: 'https://www.googleapis.com/oauth2/v1/certs', auth_uri: 'https://accounts.google.com/o/oauth2/auth', client_email: '<account>@<project>.gserviceaccount.com', client_id: '<client-id>', client_x509_cert_url: 'https://www.googleapis.com/robot/v1/metadata/x509/bโฆ', private_key: '-----BEGIN PRIVATEโฆ', โฆ}. A total of 3 errors were encountered. in .../vendor/cuyz/valinor/src/Mapper/TypeTreeMapper.php:38
Stack trace:
#0 .../vendor/kreait/firebase-php/src/Firebase/Valinor/Mapper.php(58): CuyZ\Valinor\Mapper\TypeTreeMapper->map('Kreait\\Firebase...', Object(Kreait\Firebase\Valinor\Source))
#1 .../vendor/kreait/firebase-php/src/Firebase/Factory.php(762): Kreait\Firebase\Valinor\Mapper->map('Kreait\\Firebase...', Object(Kreait\Firebase\Valinor\Source))
#2 .../vendor/kreait/firebase-php/src/Firebase/Factory.php(159): Kreait\Firebase\Factory->mapServiceAccount('/var/www/vhosts...')
#3 .../app/Jobs/PushNotificationJob.php(231): Kreait\Firebase\Factory->withServiceAccount('/var/www/vhosts...')
#4 .../app/Jobs/PushNotificationJob.php(168): App\Jobs\PushNotificationJob->send('...', Object(Kreait\Firebase\Messaging\CloudMessage), App\Enums\Platform::ANDROID)
#5 .../vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): App\Jobs\PushNotificationJob->handle(Object(App\Repositories\UserRepository))
#6 .../vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\Container\BoundMethod::{closure:Illuminate\Container\BoundMethod::call():35}()
#7 .../vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#8 .../vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#9 .../vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#10 .../vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(129): Illuminate\Container\Container->call(Array)
#11 .../vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Bus\Dispatcher->{closure:Illuminate\Bus\Dispatcher::dispatchNow():126}(Object(App\Jobs\PushNotificationJob))
#12 .../vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\Pipeline\Pipeline->{closure:Illuminate\Pipeline\Pipeline::prepareDestination():178}(Object(App\Jobs\PushNotificationJob))
#13 .../vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(133): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#14 .../vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(134): Illuminate\Bus\Dispatcher->dispatchNow(Object(App\Jobs\PushNotificationJob), false)
#15 .../vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Queue\CallQueuedHandler->{closure:Illuminate\Queue\CallQueuedHandler::dispatchThroughMiddleware():127}(Object(App\Jobs\PushNotificationJob))
#16 .../vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\Pipeline\Pipeline->{closure:Illuminate\Pipeline\Pipeline::prepareDestination():178}(Object(App\Jobs\PushNotificationJob))
#17 .../vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(127): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#18 .../vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(68): Illuminate\Queue\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\Queue\Jobs\BeanstalkdJob), Object(App\Jobs\PushNotificationJob))
#19 .../vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\Queue\CallQueuedHandler->call(Object(Illuminate\Queue\Jobs\BeanstalkdJob), Array)
#20 .../vendor/laravel/framework/src/Illuminate/Queue/Worker.php(487): Illuminate\Queue\Jobs\Job->fire()
#21 .../vendor/laravel/framework/src/Illuminate/Queue/Worker.php(437): Illuminate\Queue\Worker->process('beanstalkd', Object(Illuminate\Queue\Jobs\BeanstalkdJob), Object(Illuminate\Queue\WorkerOptions))
#22 .../vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\BeanstalkdJob), 'beanstalkd', Object(Illuminate\Queue\WorkerOptions))
#23 .../vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(148): Illuminate\Queue\Worker->daemon('beanstalkd', 'queue', Object(Illuminate\Queue\WorkerOptions))
#24 .../vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(131): Illuminate\Queue\Console\WorkCommand->runWorker('beanstalkd', 'queue')
#25 .../vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\Queue\Console\WorkCommand->handle()
#26 .../vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\Container\BoundMethod::{closure:Illuminate\Container\BoundMethod::call():35}()
#27 .../vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#28 .../vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#29 .../vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#30 .../vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\Container\Container->call(Array)
#31 .../vendor/symfony/console/Command/Command.php(341): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#32 .../vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#33 .../vendor/symfony/console/Application.php(1102): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#34 .../vendor/symfony/console/Application.php(356): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#35 .../vendor/symfony/console/Application.php(195): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#36 .../vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(197): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#37 .../artisan(35): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#38 {main}
Next Kreait\Firebase\Exception\InvalidArgumentException: Could not map type `Kreait\Firebase\ServiceAccount`:
- `projectId`: Value *missing* is not a valid string.
- `clientEmail`: Value *missing* is not a valid string.
- `privateKey`: Value *missing* is not a valid string. in .../vendor/kreait/firebase-php/src/Firebase/Valinor/Mapper.php:68
Stack trace:
#0 .../vendor/kreait/firebase-php/src/Firebase/Factory.php(762): Kreait\Firebase\Valinor\Mapper->map('Kreait\\Firebase...', Object(Kreait\Firebase\Valinor\Source))
#1 .../vendor/kreait/firebase-php/src/Firebase/Factory.php(159): Kreait\Firebase\Factory->mapServiceAccount('/var/www/vhosts...')
#2 .../app/Jobs/PushNotificationJob.php(231): Kreait\Firebase\Factory->withServiceAccount('/var/www/vhosts...')
#3 .../app/Jobs/PushNotificationJob.php(168): App\Jobs\PushNotificationJob->send('...', Object(Kreait\Firebase\Messaging\CloudMessage), App\Enums\Platform::ANDROID)
#4 .../vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): App\Jobs\PushNotificationJob->handle(Object(App\Repositories\UserRepository))
#5 .../vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\Container\BoundMethod::{closure:Illuminate\Container\BoundMethod::call():35}()
#6 .../vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#7 .../vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#8 .../vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#9 .../vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(129): Illuminate\Container\Container->call(Array)
#10 .../vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Bus\Dispatcher->{closure:Illuminate\Bus\Dispatcher::dispatchNow():126}(Object(App\Jobs\PushNotificationJob))
#11 .../vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\Pipeline\Pipeline->{closure:Illuminate\Pipeline\Pipeline::prepareDestination():178}(Object(App\Jobs\PushNotificationJob))
#12 .../vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(133): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#13 .../vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(134): Illuminate\Bus\Dispatcher->dispatchNow(Object(App\Jobs\PushNotificationJob), false)
#14 .../vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Queue\CallQueuedHandler->{closure:Illuminate\Queue\CallQueuedHandler::dispatchThroughMiddleware():127}(Object(App\Jobs\PushNotificationJob))
#15 .../vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(137): Illuminate\Pipeline\Pipeline->{closure:Illuminate\Pipeline\Pipeline::prepareDestination():178}(Object(App\Jobs\PushNotificationJob))
#16 .../vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(127): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#17 .../vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(68): Illuminate\Queue\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\Queue\Jobs\BeanstalkdJob), Object(App\Jobs\PushNotificationJob))
#18 .../vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(102): Illuminate\Queue\CallQueuedHandler->call(Object(Illuminate\Queue\Jobs\BeanstalkdJob), Array)
#19 .../vendor/laravel/framework/src/Illuminate/Queue/Worker.php(487): Illuminate\Queue\Jobs\Job->fire()
#20 .../vendor/laravel/framework/src/Illuminate/Queue/Worker.php(437): Illuminate\Queue\Worker->process('beanstalkd', Object(Illuminate\Queue\Jobs\BeanstalkdJob), Object(Illuminate\Queue\WorkerOptions))
#21 .../vendor/laravel/framework/src/Illuminate/Queue/Worker.php(201): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\BeanstalkdJob), 'beanstalkd', Object(Illuminate\Queue\WorkerOptions))
#22 .../vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(148): Illuminate\Queue\Worker->daemon('beanstalkd', 'queue', Object(Illuminate\Queue\WorkerOptions))
#23 .../vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(131): Illuminate\Queue\Console\WorkCommand->runWorker('beanstalkd', 'queue')
#24 .../vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\Queue\Console\WorkCommand->handle()
#25 .../vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\Container\BoundMethod::{closure:Illuminate\Container\BoundMethod::call():35}()
#26 .../vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#27 .../vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#28 .../vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#29 .../vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\Container\Container->call(Array)
#30 .../vendor/symfony/console/Command/Command.php(341): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#31 .../vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#32 .../vendor/symfony/console/Application.php(1102): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#33 .../vendor/symfony/console/Application.php(356): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#34 .../vendor/symfony/console/Application.php(195): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#35 .../vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(197): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#36 .../artisan(35): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#37 {main}
Additional information
The converter appears to not be applied, resulting in Valinor trying to map snake_case keys directly to camelCase properties, which fails validation. The error shows the original snake_case keys in the input while complaining about missing camelCase properties.
Manually convert the keys before passing to the factory is a workaround.
Unfortunately, I wasn't able to reproduce the problem with a service account file, neither with just the SDK nor within a Laravel project using the SDK. The service account file looks like this on my machine:
{
"type": "service_account",
"project_id": "my-project",
"private_key_id": "abc",
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
"client_email": "[email protected]",
"client_id": "12345",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/service-account-abc%40my-project.iam.gserviceaccount.com"
}
Could you share yours (redacted of course), if it does look different?
If possible, could you also require kreait/firebase-php explicitly in your composer.json with earlier releases down to the one where it works again? I hope we can reconstruct where the problem might have been introduced thenโฆ
Thanks!
The strange thing is that I also cannot reproduce the issue on my Macbook (locally running PHP 8.5). However, on our production server I am having this issue. I noticed that the "old" configuration works up to 7.20. From version 7.21 it is broken.
Production server runs on PHP 8.4.15 with OS Ubuntu 24.04.
My service key looks kind of the same as above, so that is not the issue.
I'm sorry, communicated the wrong version since when it was broken. I've updated my message above.
Details:
[[email protected] current]# sudo -u www-data composer update kreait/firebase-php
Loading composer repositories with package information
Updating dependencies
Lock file operations: 0 installs, 1 update, 0 removals
- Upgrading kreait/firebase-php (7.19.0 => 7.20.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 0 installs, 1 update, 0 removals
- Downloading kreait/firebase-php (7.20.0)
- Upgrading kreait/firebase-php (7.19.0 => 7.20.0): Extracting archive
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
INFO Discovering packages.
kamerk22/amazongiftcode ..................................................................................................................... DONE
kreait/laravel-firebase ..................................................................................................................... DONE
laravel/sail ................................................................................................................................ DONE
laravel/tinker .............................................................................................................................. DONE
nesbot/carbon ............................................................................................................................... DONE
nunomaduro/collision ........................................................................................................................ DONE
nunomaduro/termwind ......................................................................................................................... DONE
spatie/laravel-ignition ..................................................................................................................... DONE
tailflow/laravel-orion ...................................................................................................................... DONE
134 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi
INFO No publishable resources for tag [laravel-assets].
No security vulnerability advisories found.
[[email protected] current]# sudo -u www-data php artisan app:push eC8aUnb<key here>DKgJQ "test" "test 7.20" -vvv
[2025-12-10 12:14:12] [debug] Starting artisan command 'app:push' with arguments: {"command":"app:push","token":"eC8aUnb<key here>DKgJQ","title":"test","message":"test 7.20"}
[2025-12-10 12:14:14] [debug] Send out push message to token: eC8aUnb<key here>DKgJQ
[2025-12-10 12:14:14] [debug] Using credentials file: /var/www/vhosts/<project>/key.json
[2025-12-10 12:14:14] [debug] Created message payload: array (
'notification' =>
array (
'title' => 'test',
'body' => 'test 7.20',
),
'android' =>
array (
'notification' =>
array (
'title' => 'test',
'body' => 'test 7.20',
),
),
'token' => 'eC8aUnb<key here>DKgJQ',
)
[2025-12-10 12:14:14] [debug] Sending message
[2025-12-10 12:14:15] [debug] Received response: array (
'name' => '<project>/messages/<message-id>',
)
Message has been sent!
[[email protected] current]# nano composer.json
[[email protected] current]# sudo -u www-data composer update kreait/firebase-php
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 1 update, 0 removals
- Locking cuyz/valinor (2.3.1)
- Upgrading kreait/firebase-php (7.20.0 => 7.21.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 1 update, 0 removals
- Downloading cuyz/valinor (2.3.1)
- Installing cuyz/valinor (2.3.1): Extracting archive
- Upgrading kreait/firebase-php (7.20.0 => 7.21.0): Extracting archive
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
INFO Discovering packages.
kamerk22/amazongiftcode ..................................................................................................................... DONE
kreait/laravel-firebase ..................................................................................................................... DONE
laravel/sail ................................................................................................................................ DONE
laravel/tinker .............................................................................................................................. DONE
nesbot/carbon ............................................................................................................................... DONE
nunomaduro/collision ........................................................................................................................ DONE
nunomaduro/termwind ......................................................................................................................... DONE
spatie/laravel-ignition ..................................................................................................................... DONE
tailflow/laravel-orion ...................................................................................................................... DONE
135 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi
INFO No publishable resources for tag [laravel-assets].
No security vulnerability advisories found.
[[email protected] current]#
[[email protected] current]# sudo -u www-data php artisan app:push eC8aUnb<key here>DKgJQ "test" "test 7.21" -vvv
[2025-12-10 12:14:45] [debug] Starting artisan command 'app:push' with arguments: {"command":"app:push","token":"eC8aUnb<key here>DKgJQ","title":"test","message":"test 7.21"}
[2025-12-10 12:14:47] [error] Could not map type `Kreait\Firebase\ServiceAccount`:
- `projectId`: Value *missing* is not a valid string.
- `clientEmail`: Value *missing* is not a valid string.
- `clientId`: Value *missing* is not a valid string.
- `privateKey`: Value *missing* is not a valid string.
- `privateKeyId`: Value *missing* is not a valid string.
- `authUri`: Value *missing* is not a valid string.
- `tokenUri`: Value *missing* is not a valid string.
- `authProviderX509CertUrl`: Value *missing* is not a valid string.
- `clientX509CertUrl`: Value *missing* is not a valid string.
[2025-12-10 12:14:47] [error] Could not map type `Kreait\Firebase\ServiceAccount`:
- `projectId`: Value *missing* is not a valid string.
- `clientEmail`: Value *missing* is not a valid string.
- `clientId`: Value *missing* is not a valid string.
- `privateKey`: Value *missing* is not a valid string.
- `privateKeyId`: Value *missing* is not a valid string.
- `authUri`: Value *missing* is not a valid string.
- `tokenUri`: Value *missing* is not a valid string.
- `authProviderX509CertUrl`: Value *missing* is not a valid string.
- `clientX509CertUrl`: Value *missing* is not a valid string.
Kreait\Firebase\Exception\InvalidArgumentException
Could not map type `Kreait\Firebase\ServiceAccount`:
- `projectId`: Value *missing* is not a valid string.
- `clientEmail`: Value *missing* is not a valid string.
- `clientId`: Value *missing* is not a valid string.
- `privateKey`: Value *missing* is not a valid string.
- `privateKeyId`: Value *missing* is not a valid string.
- `authUri`: Value *missing* is not a valid string.
- `tokenUri`: Value *missing* is not a valid string.
- `authProviderX509CertUrl`: Value *missing* is not a valid string.
- `clientX509CertUrl`: Value *missing* is not a valid string.
at vendor/kreait/firebase-php/src/Firebase/Valinor/Mapper.php:68
64โ
65โ $message = "Could not map type `$signature`:".PHP_EOL;
66โ $message .= implode(PHP_EOL, $errorMessages);
67โ
โ 68โ throw new InvalidArgumentException($message, 0, $e);
69โ }
70โ }
71โ }
72โ
So weird ๐. Unfortunately I don't have an Ubuntu 24.04 environment available to test it there as well, but something must be different in the two environments ๐ค. To be honest, I have no idea what the reason could be. Clearly it is related to the introduction of Valinor, so it shouldn't matter if you use v7.21 or 7.24โฆ just to have this out of the way, could you try a sudo -u www-data composer update --with-all-dependencies (I noticed you didn't use -W/--with-all-dependencies before)?
I just did so. See:
[[email protected] current]# nano composer.json
[[email protected] current]# sudo -u www-data composer update --with-all-dependencies
Loading composer repositories with package information
Updating dependencies
Lock file operations: 0 installs, 2 updates, 1 removal
- Removing cuyz/valinor (2.3.1)
- Upgrading driftingly/rector-laravel (2.1.6 => 2.1.7)
- Downgrading kreait/firebase-php (7.21.0 => 7.20.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 0 installs, 2 updates, 1 removal
- Downloading driftingly/rector-laravel (2.1.7)
- Removing cuyz/valinor (2.3.1)
- Upgrading driftingly/rector-laravel (2.1.6 => 2.1.7): Extracting archive
- Downgrading kreait/firebase-php (7.21.0 => 7.20.0): Extracting archive
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
INFO Discovering packages.
kamerk22/amazongiftcode ..................................................................................................................... DONE
kreait/laravel-firebase ..................................................................................................................... DONE
laravel/sail ................................................................................................................................ DONE
laravel/tinker .............................................................................................................................. DONE
nesbot/carbon ............................................................................................................................... DONE
nunomaduro/collision ........................................................................................................................ DONE
nunomaduro/termwind ......................................................................................................................... DONE
spatie/laravel-ignition ..................................................................................................................... DONE
tailflow/laravel-orion ...................................................................................................................... DONE
134 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi
INFO No publishable resources for tag [laravel-assets].
No security vulnerability advisories found.
[[email protected] current]# sudo -u www-data php artisan app:push eC8aUnb<key here>DKgJQ "test" "test 7.20" -vvv
[2025-12-10 13:29:03] [debug] Starting artisan command 'app:push' with arguments: {"command":"app:push","token":"eC8aUnb<key here>DKgJQ","title":"test","message":"test 7.20"}
[2025-12-10 13:29:05] [debug] Send out push message to token: eC8aUnb<key here>DKgJQ
[2025-12-10 13:29:05] [debug] Using credentials file: /var/www/vhosts/<project>/key.json
[2025-12-10 13:29:05] [debug] Created message payload: array (
'notification' =>
array (
'title' => 'test',
'body' => 'test 7.20',
),
'android' =>
array (
'notification' =>
array (
'title' => 'test',
'body' => 'test 7.20',
),
),
'token' => 'eC8aUnb<key here>DKgJQ',
)
[2025-12-10 13:29:05] [debug] Sending message
[2025-12-10 13:29:05] [debug] Received response: array (
'name' => '<project>/messages/<message-id>',
)
Message has been sent!
[[email protected] current]# nano composer.json
[[email protected] current]# sudo -u www-data composer update --with-all-dependencies
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 1 update, 0 removals
- Locking cuyz/valinor (2.3.1)
- Upgrading kreait/firebase-php (7.20.0 => 7.21.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 1 update, 0 removals
- Installing cuyz/valinor (2.3.1): Extracting archive
- Upgrading kreait/firebase-php (7.20.0 => 7.21.0): Extracting archive
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
INFO Discovering packages.
kamerk22/amazongiftcode ..................................................................................................................... DONE
kreait/laravel-firebase ..................................................................................................................... DONE
laravel/sail ................................................................................................................................ DONE
laravel/tinker .............................................................................................................................. DONE
nesbot/carbon ............................................................................................................................... DONE
nunomaduro/collision ........................................................................................................................ DONE
nunomaduro/termwind ......................................................................................................................... DONE
spatie/laravel-ignition ..................................................................................................................... DONE
tailflow/laravel-orion ...................................................................................................................... DONE
135 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi
INFO No publishable resources for tag [laravel-assets].
No security vulnerability advisories found.
[[email protected] current]# sudo -u www-data php artisan app:push eC8aUnb<key here>DKgJQ "test" "test 7.21" -vvv
[2025-12-10 13:29:48] [debug] Starting artisan command 'app:push' with arguments: {"command":"app:push","token":"eC8aUnb<key here>DKgJQ","title":"test","message":"test 7.21"}
[2025-12-10 13:29:50] [error] Could not map type `Kreait\Firebase\ServiceAccount`:
- `projectId`: Value *missing* is not a valid string.
- `clientEmail`: Value *missing* is not a valid string.
- `clientId`: Value *missing* is not a valid string.
- `privateKey`: Value *missing* is not a valid string.
- `privateKeyId`: Value *missing* is not a valid string.
- `authUri`: Value *missing* is not a valid string.
- `tokenUri`: Value *missing* is not a valid string.
- `authProviderX509CertUrl`: Value *missing* is not a valid string.
- `clientX509CertUrl`: Value *missing* is not a valid string.
[2025-12-10 13:29:50] [error] Could not map type `Kreait\Firebase\ServiceAccount`:
- `projectId`: Value *missing* is not a valid string.
- `clientEmail`: Value *missing* is not a valid string.
- `clientId`: Value *missing* is not a valid string.
- `privateKey`: Value *missing* is not a valid string.
- `privateKeyId`: Value *missing* is not a valid string.
- `authUri`: Value *missing* is not a valid string.
- `tokenUri`: Value *missing* is not a valid string.
- `authProviderX509CertUrl`: Value *missing* is not a valid string.
- `clientX509CertUrl`: Value *missing* is not a valid string.
Kreait\Firebase\Exception\InvalidArgumentException
Could not map type `Kreait\Firebase\ServiceAccount`:
- `projectId`: Value *missing* is not a valid string.
- `clientEmail`: Value *missing* is not a valid string.
- `clientId`: Value *missing* is not a valid string.
- `privateKey`: Value *missing* is not a valid string.
- `privateKeyId`: Value *missing* is not a valid string.
- `authUri`: Value *missing* is not a valid string.
- `tokenUri`: Value *missing* is not a valid string.
- `authProviderX509CertUrl`: Value *missing* is not a valid string.
- `clientX509CertUrl`: Value *missing* is not a valid string.
at vendor/kreait/firebase-php/src/Firebase/Valinor/Mapper.php:68
64โ
65โ $message = "Could not map type `$signature`:".PHP_EOL;
66โ $message .= implode(PHP_EOL, $errorMessages);
67โ
โ 68โ throw new InvalidArgumentException($message, 0, $e);
69โ }
70โ }
71โ }
72โ
1 vendor/cuyz/valinor/src/Mapper/TypeTreeMapper.php:38
CuyZ\Valinor\Mapper\TypeTreeMapperError::("Could not map type `Kreait\Firebase\ServiceAccount` with value iterable{auth_provider_x509_cert_url: 'https://www.googleapis.com/oauth2/v1/certs', auth_uri: 'https://accounts.google.com/o/oauth2/auth', client_email: '<name>@<project>.iam.gserviceaccount.com', client_id: '<clientid>', client_x509_cert_url: 'https://www.googleapis.com/robot/v1/metadata/x509/bโฆ', private_key: '-----BEGIN PRIVATEโฆ', โฆ}. A total of 9 errors were encountered.")
2 vendor/kreait/firebase-php/src/Firebase/Valinor/Mapper.php:58
CuyZ\Valinor\Mapper\TypeTreeMapper::map("Kreait\Firebase\ServiceAccount", Object(Kreait\Firebase\Valinor\Source))
3 vendor/kreait/firebase-php/src/Firebase/Factory.php:742
Kreait\Firebase\Valinor\Mapper::map("Kreait\Firebase\ServiceAccount", Object(Kreait\Firebase\Valinor\Source))
4 vendor/kreait/firebase-php/src/Firebase/Factory.php:151
Kreait\Firebase\Factory::mapServiceAccount("/var/www/vhosts/<project>/key.json")
5 app/Console/Commands/SendPush.php:80
Kreait\Firebase\Factory::withServiceAccount("/var/www/vhosts/<project>/key.json")
6 vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:36
App\Console\Commands\SendPush::handle()
7 vendor/laravel/framework/src/Illuminate/Container/Util.php:43
Illuminate\Container\BoundMethod::{closure:Illuminate\Container\BoundMethod::call():35}()
8 vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:96
Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
9 vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:35
Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Object(Closure))
10 vendor/laravel/framework/src/Illuminate/Container/Container.php:799
Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), [])
11 vendor/laravel/framework/src/Illuminate/Console/Command.php:211
Illuminate\Container\Container::call()
12 vendor/symfony/console/Command/Command.php:341
Illuminate\Console\Command::execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
13 vendor/laravel/framework/src/Illuminate/Console/Command.php:180
Symfony\Component\Console\Command\Command::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
14 vendor/symfony/console/Application.php:1102
Illuminate\Console\Command::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
15 vendor/symfony/console/Application.php:356
Symfony\Component\Console\Application::doRunCommand(Object(App\Console\Commands\SendPush), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
16 vendor/symfony/console/Application.php:195
Symfony\Component\Console\Application::doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
17 vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:197
Symfony\Component\Console\Application::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
18 artisan:35
Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
We also did another test on an Apple running PHP 8.4, but it also works fine there. I really have no clue what is causing this.
So I have created this test file which pinpoints the problem a bit more:
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use Kreait\Firebase\ServiceAccount;
use Kreait\Firebase\Valinor\Mapper;
use Kreait\Firebase\Valinor\Source;
echo "=== Valinor Converter Issue Diagnostic ===\n\n";
// Display environment info
echo "ENVIRONMENT:\n";
echo "------------\n";
echo "PHP Version: " . PHP_VERSION . "\n";
$composer = json_decode(file_get_contents(__DIR__ . '/vendor/composer/installed.json'), true);
foreach ($composer['packages'] ?? [] as $package) {
if ($package['name'] === 'cuyz/valinor') {
echo "Valinor Version: {$package['version']}\n";
}
if ($package['name'] === 'kreait/firebase-php') {
echo "kreait/firebase-php: {$package['version']}\n";
}
}
echo "\n";
$testData = [
'type' => 'service_account',
'project_id' => 'test-project-123',
'private_key_id' => 'abc123',
'private_key' => '-----BEGIN PRIVATE KEY-----\ntest\n-----END PRIVATE KEY-----\n',
'client_email' => '[email protected]',
'client_id' => '123456789',
];
echo "TEST DATA (snake_case keys):\n";
echo json_encode($testData, JSON_PRETTY_PRINT) . "\n\n";
echo "=" . str_repeat("=", 70) . "\n\n";
// TEST 1: Trace exact Kreait Mapper flow
echo "TEST: Exact Kreait\\Firebase\\Valinor\\Mapper Flow\n";
echo str_repeat("-", 70) . "\n";
try {
echo "Step 1: new Mapper(null)\n";
$mapper = new Mapper(null);
echo "Step 2: ->allowSuperfluousKeys()\n";
$mapper = $mapper->allowSuperfluousKeys();
echo "Step 3: ->snakeToCamelCase()\n";
$mapper = $mapper->snakeToCamelCase();
echo "Step 4: ->map(ServiceAccount::class, \$testData)\n\n";
$result = $mapper->map(ServiceAccount::class, Source::parse($testData));
echo "โ SUCCESS!\n";
echo " projectId: {$result->projectId}\n";
echo " clientEmail: {$result->clientEmail}\n\n";
} catch (Throwable $e) {
echo "โ FAILED!\n";
echo " Error: " . $e->getMessage() . "\n\n";
}
Output on my mac:
=== Valinor Converter Issue Diagnostic ===
ENVIRONMENT:
------------
PHP Version: 8.5.0
Valinor Version: 2.3.1
kreait/firebase-php: 7.24.0
TEST DATA (snake_case keys):
{
"type": "service_account",
"project_id": "test-project-123",
"private_key_id": "abc123",
"private_key": "-----BEGIN PRIVATE KEY-----\\ntest\\n-----END PRIVATE KEY-----\\n",
"client_email": "[email protected]",
"client_id": "123456789"
}
=======================================================================
TEST: Exact Kreait\Firebase\Valinor\Mapper Flow
----------------------------------------------------------------------
Step 1: new Mapper(null)
Step 2: ->allowSuperfluousKeys()
Step 3: ->snakeToCamelCase()
Step 4: ->map(ServiceAccount::class, $testData)
โ SUCCESS!
projectId: test-project-123
clientEmail: [email protected]
Output on the server:
=== Valinor Converter Issue Diagnostic ===
ENVIRONMENT:
------------
PHP Version: 8.4.15
Valinor Version: 2.3.1
kreait/firebase-php: 7.24.0
TEST DATA (snake_case keys):
{
"type": "service_account",
"project_id": "test-project-123",
"private_key_id": "abc123",
"private_key": "-----BEGIN PRIVATE KEY-----\\ntest\\n-----END PRIVATE KEY-----\\n",
"client_email": "[email protected]",
"client_id": "123456789"
}
=======================================================================
TEST: Exact Kreait\Firebase\Valinor\Mapper Flow
----------------------------------------------------------------------
Step 1: new Mapper(null)
Step 2: ->allowSuperfluousKeys()
Step 3: ->snakeToCamelCase()
Step 4: ->map(ServiceAccount::class, $testData)
โ FAILED!
Error: Could not map type `Kreait\Firebase\ServiceAccount`:
- `projectId`: Value *missing* is not a valid string.
- `clientEmail`: Value *missing* is not a valid string.
- `privateKey`: Value *missing* is not a valid string.
Thanks for the script! I spun up a VM with Ubuntu 24.04 and PHP 8.4 and didn't run into this error there as well :/.
These are the PHP packages I installed there, in case you want to compare them with yours:
jg@ubuntu:~/test$ apt list --installed | grep php
php-common/noble,now 2:99~+ubuntu24.04.1+deb.sury.org+1 all [installed,automatic]
php8.4-cli/noble,now 8.4.15-1+ubuntu24.04.1+deb.sury.org+1 arm64 [installed]
php8.4-common/noble,now 8.4.15-1+ubuntu24.04.1+deb.sury.org+1 arm64 [installed]
php8.4-curl/noble,now 8.4.15-1+ubuntu24.04.1+deb.sury.org+1 arm64 [installed]
php8.4-grpc/noble,now 1.76.0-2+ubuntu24.04.1+deb.sury.org+1 arm64 [installed]
php8.4-mbstring/noble,now 8.4.15-1+ubuntu24.04.1+deb.sury.org+1 arm64 [installed]
php8.4-opcache/noble,now 8.4.15-1+ubuntu24.04.1+deb.sury.org+1 arm64 [installed,automatic]
php8.4-readline/noble,now 8.4.15-1+ubuntu24.04.1+deb.sury.org+1 arm64 [installed,automatic]
php8.4-zip/noble,now 8.4.15-1+ubuntu24.04.1+deb.sury.org+1 arm64 [installed]
Just for funsies, could you try composer require -W kreait/firebase-php:8.x-dev?
@jeromegamez , we have done some digging and we have found a clue. Enabling opcache is causing this issue.
I have cloned the repo and created 2 github actions which proof that opcache is the cause:
See: Test 1, opcache enabled, which fails: https://github.com/teyeheimans/firebase-php/actions/runs/20127224988/job/57759611348
Test 2, opcache disabled, which succeeds: https://github.com/teyeheimans/firebase-php/actions/runs/20127335745/job/57759995786
The exact cause of why the code fails with opcache enabled is not clear yet. However, we now know in which direction to look.
Great finds! With the settings in your workflow
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=1024
opcache.max_accelerated_files=100000
opcache.validate_timestamps=1
opcache.revalidate_freq=5
opcache.save_comments=0
I was able to recreate the issue, also on my local machine. The culprit seems to be opcache.save_comments=0 - with the line the script fails, when I comment it, it works. Can you confirm this?
Aaaaha!! https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.save-comments
opcache.save_commentsIf disabled, all documentation comments will be discarded from the opcode cache to reduce the size of the optimised code. Disabling this configuration directive may break applications and frameworks that rely on comment parsing for annotations, including Doctrine, Zend Framework 2 and PHPUnit.
I can confirm that it now works. We have enabled the opcache.save_comments on our servers now. Thanks for your help.
I'm glad this didn't remain a mistery after all ๐ฎโ๐จ
@romm Forgive me for pulling you in without prior notice ๐. The SDK doesn't use the mapper cache unless explicitly provided (I didn't want to add a hard dependency to the file system in case the SDK is used in an environment with read-only filesystems).
Even with the cache and warmup, in the build step, we would need opcache comments to be enabled. On the target system, with the cache files in place, do you know from the top of your head if it would work if opcache comments are disabled there?
I gave it a try locally and it seems that they are still required, but it was just a very quick try, and thought if someone knows, it's you ๐ฌ
Thank you for the ping! I'm glad you found a way to solve the issue. I've created https://github.com/CuyZ/Valinor/issues/767 to fix it eventually. ๐