kreait / firebase-php

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

Undisclosed dependency on guzzlehttp/psr:^2.0 #842

Closed tibbsa closed 9 months ago

tibbsa commented 9 months ago

Describe the bug

While upgrading a project to Laravel 10, I ran into what I think is an undocumented dependency. src/Firebase/Factory.php uses GuzzleHttp\Psr7\HttpFactory, but that doesn't appear to be a part of the "guzzlehttp/guzzlepackage (which is listed incomposer.json) and is instead a part ofguzzlehttp/psr7` (from v2.x upward).

I ran into the issue because I have another dependency that currently hard-depends on guzzlehttp/psr7:1.6 which silently prevented guzzlehttp/psr7:2.x from being installed. While the upgrade 'succeeded', my Laravel notifications then failed because of the missing HttpFactory class.

If my understanding is right, then this is simply a matter of listing guzzlehttp/psr7:^2.0 in composer.json for this project. That won't solve my current dependency conflict with the other package, but at least it would have flagged it as a problem earlier in the upgrade process.

Installed packages

{
    "name": "<redacted>",
    "type": "project",
    "description": "<redacted>",
    "keywords": [
        "<redacted>",
        "<redacted>",
        "<redacted>",
        "<redacted>",
        "<redacted>"
    ],
    "license": "MIT",
    "require": {
        "php": "^8.1",
        "ext-curl": "*",
        "ext-imagick": "*",
        "ext-intl": "*",
        "ext-json": "*",
        "ext-simplexml": "*",
        "backpack/crud": "^6.0",
        "backpack/pro": "^2.0",
        "backpack/theme-coreuiv2": "^1.2",
        "darkaonline/l5-swagger": "^8.3",
        "doctrine/dbal": "^3.5",
        "dompdf/dompdf": "^2.0",
        "dragon-code/laravel-actions": "^4.0",
        "guzzlehttp/guzzle": "^7.8",
        "ilzrv/laravel-slow-query-detector": "^2.0",
        "jamesmills/laravel-notification-rate-limit": "^2.0",
        "kreait/firebase-php": "^7.0",
        "laravel-notification-channels/fcm": "^3.0",
        "laravel/cashier": "^14.7",
        "laravel/framework": "^10.32",
        "laravel/sanctum": "^3.2",
        "laravel/tinker": "^2.8",
        "league/flysystem-aws-s3-v3": "^3.0",
        "livewire/livewire": "^3.0",
        "ncjoes/office-converter": "^1.0",
        "orangehill/iseed": "^3.0",
        "paquettg/php-html-parser": "^3.1",
        "php-ffmpeg/php-ffmpeg": "^1.1",
        "sendinblue/api-v3-sdk": "8.x.x",
        "silber/bouncer": "^1.0",
        "spatie/laravel-medialibrary": "^10.7",
        "spatie/pdf-to-image": "^2.2",
        "staudenmeir/eloquent-json-relations": "^1.8",
        "symplify/vendor-patches": "^11.1",
        "torann/geoip": "^3.0",
        "troydavisson/phrets": "^2.6"
    },
    "require-dev": {
        "backpack/generators": "^4.0",
        "barryvdh/laravel-ide-helper": "^2.13",
        "fakerphp/faker": "^1.9.1",
        "laravel/sail": "^1.18",
        "mockery/mockery": "^1.4.4",
        "nunomaduro/collision": "^6.1",
        "nunomaduro/larastan": "^2.0",
        "phpunit/phpunit": "^9.5.10",
        "spatie/laravel-ignition": "^2.0"
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true,
        "allow-plugins": {
            "cweagans/composer-patches": true
        }
    },
    "extra": {
        "patches": {
            "ilzrv/laravel-slow-query-detector": [
                "patches/ilzrv-laravel-slow-query-detector-src-serviceprovider-php.patch",
                "patches/ilzrv-laravel-slow-query-detector-config-sqd-php.patch"
            ]
        }
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/",
            "Tallium\\SentriLock\\": "packages/Tallium/SentriLock/src"
        },
        "files": [
            "app/Support/helpers.php"
        ]
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        },
        "files": [
            "app/Support/helpers.php"
        ]
    },
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-install-cmd": ["@php -r \"file_exists('.env') || copy('.env-local', '.env');\"", "php artisan storage:link --quiet"],
        "post-update-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postUpdate"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env-local', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    },
    "repositories": [
        {
            "type": "composer",
            "url": "https://repo.backpackforlaravel.com/"
        }
    ],
    "minimum-stability": "stable",
    "prefer-stable": true
}

PHP version and extensions

composer                2.4.1     Composer package
composer-plugin-api     2.3.0     The Composer Plugin API
composer-runtime-api    2.2.2     The Composer Runtime API
ext-bcmath              8.1.24    The bcmath PHP extension
ext-calendar            8.1.24    The calendar PHP extension
ext-ctype               8.1.24    The ctype PHP extension
ext-curl                8.1.24    The curl PHP extension
ext-date                8.1.24    The date PHP extension
ext-dom                 20031129  The dom PHP extension
ext-exif                8.1.24    The exif PHP extension
ext-ffi                 8.1.24    The FFI PHP extension
ext-fileinfo            8.1.24    The fileinfo PHP extension
ext-filter              8.1.24    The filter PHP extension
ext-ftp                 8.1.24    The ftp PHP extension
ext-gd                  8.1.24    The gd PHP extension
ext-gettext             8.1.24    The gettext PHP extension
ext-hash                8.1.24    The hash PHP extension
ext-iconv               8.1.24    The iconv PHP extension
ext-igbinary            3.2.14    The igbinary PHP extension
ext-imagick             3.7.0     The imagick PHP extension
ext-imap                8.1.24    The imap PHP extension
ext-intl                8.1.24    The intl PHP extension
ext-json                8.1.24    The json PHP extension
ext-ldap                8.1.24    The ldap PHP extension
ext-libxml              8.1.24    The libxml PHP extension
ext-mbstring            8.1.24    The mbstring PHP extension
ext-memcached           3.2.0     The memcached PHP extension
ext-msgpack             2.2.0RC2  The msgpack PHP extension
ext-mysqli              8.1.24    The mysqli PHP extension
ext-mysqlnd             0         The mysqlnd PHP extension (actual version: mysqlnd 8.1.24)
ext-openssl             8.1.24    The openssl PHP extension
ext-pcntl               8.1.24    The pcntl PHP extension
ext-pcov                1.0.11    The pcov PHP extension
ext-pcre                8.1.24    The pcre PHP extension
ext-pdo                 8.1.24    The PDO PHP extension
ext-pdo_mysql           8.1.24    The pdo_mysql PHP extension
ext-pdo_pgsql           8.1.24    The pdo_pgsql PHP extension
ext-pdo_sqlite          8.1.24    The pdo_sqlite PHP extension
ext-pgsql               8.1.24    The pgsql PHP extension
ext-phar                8.1.24    The Phar PHP extension
ext-posix               8.1.24    The posix PHP extension
ext-readline            8.1.24    The readline PHP extension
ext-redis               6.0.1     The redis PHP extension
ext-reflection          8.1.24    The Reflection PHP extension
ext-session             8.1.24    The session PHP extension
ext-shmop               8.1.24    The shmop PHP extension
ext-simplexml           8.1.24    The SimpleXML PHP extension
ext-soap                8.1.24    The soap PHP extension
ext-sockets             8.1.24    The sockets PHP extension
ext-sodium              8.1.24    The sodium PHP extension
ext-spl                 8.1.24    The SPL PHP extension
ext-sqlite3             8.1.24    The sqlite3 PHP extension
ext-sysvmsg             8.1.24    The sysvmsg PHP extension
ext-sysvsem             8.1.24    The sysvsem PHP extension
ext-sysvshm             8.1.24    The sysvshm PHP extension
ext-tokenizer           8.1.24    The tokenizer PHP extension
ext-xdebug              3.2.1     The xdebug PHP extension
ext-xml                 8.1.24    The xml PHP extension
ext-xmlreader           8.1.24    The xmlreader PHP extension
ext-xmlwriter           8.1.24    The xmlwriter PHP extension
ext-xsl                 8.1.24    The xsl PHP extension
ext-zend-opcache        8.1.24    The Zend OPcache PHP extension
ext-zip                 1.19.5    The zip PHP extension
ext-zlib                8.1.24    The zlib PHP extension
lib-curl                7.81.0    The curl library
lib-curl-libssh         0.9.6     curl libssh version
lib-curl-openssl        3.0.2     curl OpenSSL version (3.0.2)
lib-curl-zlib           1.2.11    curl zlib version
lib-date-timelib        2021.19   date timelib version
lib-date-zoneinfo       0         zoneinfo ("Olson") database for date
lib-fileinfo-libmagic   540       fileinfo libmagic version
lib-gd                  2.3.3     The gd library
lib-iconv               2.35      The iconv library
lib-icu                 70.1      The ICU unicode and globalization support library
lib-icu-cldr            40        ICU CLDR project version
lib-icu-unicode         14.0.0    ICU unicode version
lib-icu-zoneinfo        2023.3    zoneinfo ("Olson") database for icu
lib-imagick-imagemagick 6.9.11.60 The imagick-imagemagick library
lib-ldap-openldap       2.5.16    OpenLDAP version of ldap
lib-libsodium           1.0.18    The libsodium library
lib-libxml              2.9.14    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.7     mbstring oniguruma version
lib-openssl             3.0.2     OpenSSL 3.0.2 15 Mar 2022
lib-pcre                10.40     The pcre library
lib-pcre-unicode        14.0.0    PCRE Unicode version support
lib-pdo_pgsql-libpq     14.9      libpq for pdo_pgsql
lib-pdo_sqlite-sqlite   3.37.2    The pdo_sqlite-sqlite library
lib-sqlite3-sqlite      3.37.2    The sqlite3-sqlite library
lib-zip-libzip          1.7.3     The zip-libzip library
lib-zlib                1.2.11    The zlib library
php                     8.1.24    The PHP interpreter
php-64bit               8.1.24    The PHP interpreter, 64bit
php-ipv6                8.1.24    The PHP interpreter, with IPv6 support

Steps to reproduce the issue.

(see above)

Error message/Stack trace

[2023-11-20 16:23:49] stage.ERROR: Class "GuzzleHttp\Psr7\HttpFactory" not found
 {"userId":76850,"exception":"[object] (Error(code: 0): Class \"GuzzleHttp\\Psr7
\\HttpFactory\" not found at /var/www/backend-app/vendor/kreait/firebase-php/src
/Firebase/Factory.php:127)
[stacktrace]
#0 /var/www/backend-app/vendor/kreait/laravel-firebase/src/FirebaseProjectManage
r.php(63): Kreait\\Firebase\\Factory->__construct()
#1 /var/www/backend-app/vendor/kreait/laravel-firebase/src/FirebaseProjectManage
r.php(33): Kreait\\Laravel\\Firebase\\FirebaseProjectManager->configure()
#2 /var/www/backend-app/vendor/laravel-notification-channels/fcm/src/FcmChannel.
php(92): Kreait\\Laravel\\Firebase\\FirebaseProjectManager->project()
#3 /var/www/backend-app/vendor/laravel-notification-channels/fcm/src/FcmChannel.
php(120): NotificationChannels\\Fcm\\FcmChannel->messaging()
#4 /var/www/backend-app/vendor/laravel-notification-channels/fcm/src/FcmChannel.
php(70): NotificationChannels\\Fcm\\FcmChannel->sendToFcm()
#5 /var/www/backend-app/vendor/laravel/framework/src/Illuminate/Notifications/No
tificationSender.php(148): NotificationChannels\\Fcm\\FcmChannel->send()
#6 /var/www/backend-app/vendor/laravel/framework/src/Illuminate/Notifications/No
tificationSender.php(106): Illuminate\\Notifications\\NotificationSender->sendTo
Notifiable()
...(and so on)...

Additional information

No response

jeromegamez commented 9 months ago

You're right that it's better to not use transitive dependencies and require them in the composer.json directly. I had that in the past but removed it to reduce the size of the require section. I will re-add it, thanks for bringing this up!

However, the guzzlehttp/psr7 dependency should be present, as it is included in guzzlehttp/guzzle (https://github.com/guzzle/guzzle/blob/d95d9ab74822c2ca06b31477cd6775a4a299b8e8/composer.json#L57)

Could you replace the contents of your composer.json file in the issue with the output of composer show? (I updated the issue template to suggest this by default)

If guzzlehttp/psr7 is not in the list, please try a composer update -W guzzlehttp/guzzle (or composer update -W to update all dependencies) and see if that changes anything.

jeromegamez commented 9 months ago

I will re-add it, thanks for bringing this up!

I will do this in the upcoming 8.0 release.

tibbsa commented 9 months ago

Yes, guzzlehttp/guzzle has guzzlehttp/psr7 as a dependency, but guzzlehttp/guzzle is more permissive and allows for "^1.9.1 || ^2.5.1", but you need to limit it to ^2.0 because HttpFactory was only added in the 2.x branch.

Because I have another dependency that has pegged guzzlehttp/psr7 at ^1.9.1, I have the 1.x branch installed in the project, so the dependency for guzzlehttp/guzzle is satisfied but it does not actually provide what is needed for the Firebase package.

jeromegamez commented 9 months ago

Ah, got it! Thanks for the clarification, I will do it in a new 7.x release then!

jeromegamez commented 9 months ago

Implemented in https://github.com/kreait/firebase-php/commit/c9f7ef556032f61b66711207a4d9dd9e2f46de9d and released with https://github.com/kreait/firebase-php/releases/tag/7.7.0

Thanks again!