Unable to send messaging after updating to 7.10.0
Describe the bug
Running environment: PHP8.1 / "kreait/firebase-php":7.10.0
My local development environment is: windows
The online server environment is: Debian GNU/Linux 12 x86_64 (Py3.7.16)
When I was developing locally, I had no problem using 7.10.0 and could send messages normally. When my online server was updated to 7.10.0, I could not send messages. The error message was:
URL error 0: The cURL request was retried 3 times and did not succeed. The most likely reason for the failure is that cURL was unable to rewind the body of the request and subsequent retries resulted in the same error. Turn on the debug option to see what went wrong. See https://bugs.php.net/bug.php?id=47204 for more information. (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for https://fcm.googleapis.com/v1/projects/flutter-receive-sms/messages:send
Additionally an error page is returned.
411 Error. POST requests require a Content-length header. That’s all we know
Installed packages
"kreait/firebase-php":7.10.0
PHP version and extensions
-
Steps to reproduce the issue.
public function sendCloudMessaging(string $sendType, array $params): array|bool
{
Notification::fromArray([
'title' => $params['title'],
'body' => $params['body']
]);
if (!isset($data)) {
$params['data'] = ['jump' => 'my'];
}
$notification = Notification::create($params['title'], $params['body']);
$notification = $notification->withTitle($params['title'])->withBody($params['body']);
CloudMessage::withTarget($sendType, $params[$sendType])
->withNotification($notification)
->withData($params['data']);
$message = CloudMessage::fromArray([
$sendType => $params[$sendType],
'notification' => $notification,
'data' => $params['data']
]);
try {
if (is_array($params['token'])){
if (count($params['token']) > 500){
return false;
}
$result = $this->messaging->sendMulticast($message, $params['token']);
return ['success' => $result->successes()->count(), 'fail' => $result->failures()->count()];
}else{
$result = $this->messaging->send($message);
if (array_key_exists('name', $result)){
return ['success' => 1, 'fail' => 0];
}
return false;
}
} catch (MessagingException | FirebaseException $e) {
Log::error('sendCloudMessaging error' . $e->getMessage());
return false;
}
}
Error message/Stack trace
-
Additional information
No response
When my online version was restored to 7.9.1, the functions returned to normal and messaging could be sent normally.
Someone reported something similar a few days ago, perhaps reading through that issue might help:
https://github.com/kreait/laravel-firebase/issues/219
7.10 doesn't use the legacy FCM API anymore, and uses the HTTP V1 API with HTTP/2 instead, because the legacy API will be shut down by the end of June.
I understand that it's a minor release breaking your server environment, but still, please make sure that your remote server is properly configured and and has the latest dependencies (especially cURL) installed.
I have no means of testing why it works locally but not on the server, there are too many unknowns. But if you can tell me the differences between your local and remote environment, I might be able to introduce a condition to use a fallback mechanism.
Thank you for your reply, I am looking for the problem based on your tips and I will get back to you if it is resolved.
I have the same issue. Updating 7.9 to 7.10/7.11 made me unable to send any message. I am using Webuzo panel. I installed Apache 2.4 MPM event version. I have enabled HTTP/2 protocol on apache setting. The resulting error message is the same: 411 Error. POST requests require a Content-length header. That’s all we know.
Please share the output of the following CLI commands in the environment in which you encounter the issue:
curl --version
and (as you were asked when creating the issue)
composer show --platform
curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.90 zlib/1.2.7 libidn/1.28 libssh2/1.8.0 Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz unix-sockets
composer 2.7.2 Composer package composer-plugin-api 2.6.0 The Composer Plugin API composer-runtime-api 2.2.2 The Composer Runtime API ext-bcmath 8.2.17 The bcmath PHP extension ext-bz2 8.2.17 The bz2 PHP extension ext-calendar 8.2.17 The calendar PHP extension ext-ctype 8.2.17 The ctype PHP extension ext-curl 8.2.17 The curl PHP extension ext-date 8.2.17 The date PHP extension ext-dba 8.2.17 The dba PHP extension ext-dom 20031129 The dom PHP extension ext-exif 8.2.17 The exif PHP extension ext-fileinfo 8.2.17 The fileinfo PHP extension ext-filter 8.2.17 The filter PHP extension ext-ftp 8.2.17 The ftp PHP extension ext-gd 8.2.17 The gd PHP extension ext-gettext 8.2.17 The gettext PHP extension ext-gmp 8.2.17 The gmp PHP extension ext-hash 8.2.17 The hash PHP extension ext-iconv 8.2.17 The iconv PHP extension ext-imagick 3.7.0 The imagick PHP extension ext-imap 8.2.17 The imap PHP extension ext-intl 8.2.17 The intl PHP extension ext-ioncube-loader 13.0.2 The ionCube Loader PHP extension ext-json 8.2.17 The json PHP extension ext-ldap 8.2.17 The ldap PHP extension ext-libxml 8.2.17 The libxml PHP extension ext-mailparse 3.1.2 The mailparse PHP extension ext-mbstring 8.2.17 The mbstring PHP extension ext-mcrypt 1.0.5 The mcrypt PHP extension ext-memcached 3.2.0 The memcached PHP extension ext-mysqli 8.2.17 The mysqli PHP extension ext-mysqlnd 0 The mysqlnd PHP extension (actual versi... ext-openssl 8.2.17 The openssl PHP extension ext-pcntl 8.2.17 The pcntl PHP extension ext-pcre 8.2.17 The pcre PHP extension ext-pdo 8.2.17 The PDO PHP extension ext-pdo_mysql 8.2.17 The pdo_mysql PHP extension ext-pdo_sqlite 8.2.17 The pdo_sqlite PHP extension ext-phar 8.2.17 The Phar PHP extension ext-posix 8.2.17 The posix PHP extension ext-random 8.2.17 The random PHP extension ext-reflection 8.2.17 The Reflection PHP extension ext-session 8.2.17 The session PHP extension ext-shmop 8.2.17 The shmop PHP extension ext-simplexml 8.2.17 The SimpleXML PHP extension ext-soap 8.2.17 The soap PHP extension ext-sockets 8.2.17 The sockets PHP extension ext-sodium 2.0.23 The sodium PHP extension ext-spl 8.2.17 The SPL PHP extension ext-sqlite3 8.2.17 The sqlite3 PHP extension ext-sysvmsg 8.2.17 The sysvmsg PHP extension ext-sysvsem 8.2.17 The sysvsem PHP extension ext-sysvshm 8.2.17 The sysvshm PHP extension ext-tidy 8.2.17 The tidy PHP extension ext-tokenizer 8.2.17 The tokenizer PHP extension ext-xml 8.2.17 The xml PHP extension ext-xmlreader 8.2.17 The xmlreader PHP extension ext-xmlwriter 8.2.17 The xmlwriter PHP extension ext-xsl 8.2.17 The xsl PHP extension ext-zend-opcache 8.2.17 The Zend OPcache PHP extension ext-zip 1.21.1 The zip PHP extension ext-zlib 8.2.17 The zlib PHP extension lib-bz2 1.0.6 The bz2 library lib-curl 7.87.0 The curl library 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-date-zoneinfo 2024.1 zoneinfo ("Olson") database for date lib-fileinfo-libmagic 540 fileinfo libmagic version lib-gd 2.0.35 The gd library lib-gd-freetype 2.4.12 freetype version for gd lib-gd-libjpeg 9.0 libjpeg version for gd lib-gd-libpng 1.6.30 libpng version for gd lib-gmp 6.1.0 The gmp library lib-iconv 1.14 The iconv library lib-icu 69.1 The ICU unicode and globalization suppo... lib-icu-cldr 39 ICU CLDR project version lib-icu-unicode 13.0.0 ICU unicode version lib-icu-zoneinfo 2021.1 zoneinfo ("Olson") database for icu lib-imagick-imagemagick 7.0.7.28 The imagick-imagemagick library lib-ldap-openldap 2.4.41 OpenLDAP version of ldap lib-libsodium 1.0.18 The libsodium library lib-libxml 2.9.0 libxml library version lib-libxslt 1.1.34 The libxslt library lib-libxslt-libxml 2.9.0 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-memcached-libmemcached 1.0.18 libmemcached 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.28.0 The pdo_sqlite-sqlite library lib-sqlite3-sqlite 3.28.0 The sqlite3-sqlite library lib-zip-libzip 1.7.3 The zip-libzip library lib-zlib 1.2.11 The zlib library php 8.2.17 The PHP interpreter php-64bit 8.2.17 The PHP interpreter, 64bit php-ipv6 8.2.17 The PHP interpreter, with IPv6 support
Is my problem caused by outdated curl? I am using Centos 7.9 and it seems to be stuck on curl version 7.29 though. yum update curl libcurl does nothing. It said that curl is already latest version. Even though latest version is actually 8.8.0 >_>
Thank you for providing me with the information!
HTTP/2 support has been available since version 7.47 (which was released in 2016). I believe that should indeed be the issue. However, I assume(d) that the line
lib-curl 7.87.0 The curl library
would mean that PHP is using a newer version of libcurl.
In order to test this, could you please execute the following in the environment that doesn't work?
php -i | grep HTTP2
It should output something like HTTP2 => Yes - if it shows nothing, this means your environment indeed can't send HTTP/2 requests :/.
Uh oh. The reply is dreadfully: HTTP2 => No
What can I do to fix this? Would 7.9 stop working after 30 June? I am so dead.
Uh oh. The reply is dreadfully: HTTP2 => No
What can I do to fix this? Would 7.9 stop working after 30 June? I am so dead.
I seem to be in the same situation, how to solve it?
7.9 would continue to work after June 30th - it already uses the new endpoints, but calls them synchronously instead of asynchronously since 7.10 (for better performance).
I could implement a check if HTTP/2 is supported - if it isn't, the SDK could do synchronous requests instead of asynchronous requests (which would result in the slower performance that the change improved).
I hope you can understand that I can't stop introducing new features or improve existing ones just because server dependencies are outdated. I can implement the needed checks and different behavior, but I can't do it for free.
I can get started with it as soon as I get $500 in total of GitHub sponsorships. It can be a one time sponsorship or a recurring one, as long as it reaches $500 in one month. If you make money with the help of the SDK, this shouldn't be too much.
If you don't want to go this route, you can either stay with 7.9 (and miss out on future improvements and features). The best way to solve the problem would, of course, making sure that your server environment has a current version of cURL installed. In the end, it all depends on how much you value your (or your team's) time, and the benefits of free Open Source software.
Thank you for your understanding!
https://github.com/sponsors/jeromegamez
哦哦。答复很糟糕: HTTP2 => 否
我该怎么做才能解决这个问题? 7.9 会在 6 月 30 日之后停止工作吗? 我快要崩溃了。
我刚刚解决这个问题
确实是这个http2的原因
php 的 curl 扩展 需要启用 http2
Yeah, I can confirm through my browser that my website is already served using http2. Also running curl on ssh does result in http2 working. The problem seems to be solely on my php binary. Centos 7.9 installed a precompiled version in which php's curl extension does not work with http2. Maybe I should compile it myself or something.
Thank you for the kind response, Jerome. Even though you are doing this project for free. I think it's fine to leave it like this if 7.9 will continue to work after 30 June. Don't bother with adding extra check here and there. Centos 7.9 itself will reach it's end of life soon anyway. I can always install Ubuntu 24.04 in the future.
~~It came to me (in the shower of all places 😅) that perhaps I can make it work with a small change, I remember adding something some time back that I could wrap in a condition 🤔~~
This didn't seem to be it.
Could you please test with https://github.com/kreait/firebase-php/pull/903 if this solves the issue?
Unfortunately, the end result is the same. That must be because echoing those constants on my server returning this: {"CURL_HTTP_VERSION_2":3,"CURL_HTTP_VERSION_2_0":3}
Well.. even if they are 'undefined', this pull request still won't fix the problem, because I have tried doing drastic measure. Instead of performing extra check on those constants, I simply remove the line with "->withProtocolVersion('2.0')" now. After removing that line, I got a new kind of error message. Instead of getting '411 Error. POST requests require a Content-length header. That’s all we know.' Now my php crashed with MessagingException, getMessage() returns "The message is not set."
Another drastic measure. Next, instead of removing ->withProtocolVersion('2.0'), I tried changing 2.0 to both 1.1 and 1.0. The result is, my php crashed with MessagingException, getMessage() returns "The message is not set.", again.
Hm, if the constants are set, HTTP/2 is supported by your environment, and this isn't the solution. Are you using a proxy?
I use Webuzo as control panel on Centos 7.9. It is the one who installed Apache 2.4, MySQL 8.0, PHP-FPM, PHP81 and PHP82 on my server.
For the time being, staying on 7.9 seems to be the best option, and it has no bugs or missing features, so you should be good for the foreseeable future.
But if you happen to find the reason, I'd be not the only one to appreciate if you shared it here.
My offer from a few posts ago still stands 😊 - or, of course, if it is something in the current implementation that can be done, I'll need a pointer what it is 😅
Yeah I am staying for the time being. When I have time, I will try to look at your codes to find out why simply removing ->withProtocolVersion('2.0') ends up in "The message is not set." exception. I have checked the contents of this particular file when it's version 7.9, and that line seems to be the only difference. I have to check the other files' difference too, it seems.
Why pull request #903 is rejected?. Even it doesn't solve the problem for @Daniel-Cong, the 2.0 protocol version must not be forced without verifying that is available. If this causes any other problems, composer must restrict the installation with something like "lib-curl": ">=7.33" (didn't tested it, never forced a library version in composer...).
NOTE: The required cURL library version can be found here.
HTTP/2 is needed to make sending FCM messages for several thousand, sometimes even 100K+ messages, high-performant. It'a a feature that even the official Admin Node SDK currently lacks (there's an open PR, though) and which currently sets this PHP SDK apart.
While it is less then desirable that v7.10+ break certain environments, I can't possibly be expected to think about environments that don't support a standard that has been released in 2015 and had experimental support by curl even since 2013.
Before telling me what I must or must not do, especially if you haven't tested if it works or not, consider this: I work on this project in my spare time and my work is unfunded. I aim to introduce as few breaking changes as possible, but sometimes, things break. I address these as fast as I can when a BC affects everyone. Apart from that, I do it when I find the free time, or when sponsorships allow me to reserve time.
You want me to check for outdated dependencies like cURL, I'd like people to update your outdated dependencies. This project mainly isn't used by hobby projects but by businesses earning money with it and/or spending money on their teams working with. You can invest your money either on keeping your systems up-to-date or on the maintainers of the projects you use to do work so you don't have to. If you do neither, don't tell them what they must do.
That being said: I'm open for PRs (including tests) making the feature work with old curl versions. If they are none (as usual), I will try to find the time to look into this further. But I will not revert the performance improvements that the majority of people/businesses now rely on (and who also don't fund this project).
HTTP/2 is needed to make sending FCM messages for several thousand, sometimes even 100K+ messages, high-performant. It'a a feature that even the official Admin Node SDK currently lacks (there's an open PR, though) and which currently sets this PHP SDK apart.
While it is less then desirable that v7.10+ break certain environments, I can't possibly be expected to think about environments that don't support a standard that has been released in 2015 and had experimental support by curl even since 2013.
Before telling me what I must or must not do, especially if you haven't tested if it works or not, consider this: I work on this project in my spare time and my work is unfunded. I aim to introduce as few breaking changes as possible, but sometimes, things break. I address these as fast as I can when a BC affects everyone. Apart from that, I do it when I find the free time, or when sponsorships allow me to reserve time.
You want me to check for outdated dependencies like cURL, I'd like people to update your outdated dependencies. This project mainly isn't used by hobby projects but by businesses earning money with it and/or spending money on their teams working with. You can invest your money either on keeping your systems up-to-date or on the maintainers of the projects you use to do work so you don't have to. If you do neither, don't tell them what they must do.
That being said: I'm open for PRs (including tests) making the feature work with old curl versions. If they are none (as usual), I will try to find the time to look into this further. But I will not revert the performance improvements that the majority of people/businesses now rely on (and who also don't fund this project).
First of all, sorry if the tone of the comment is not the right one, I appreciate the work done in any open source project because I do it too.
You know that update dependencies is not always possible. For example, CentOS 7 is still widely used (EOL is june 30th) and it comes with cURL 7.29.
It's not about what we think as open source developers (people must update it's dependencies), it's about the usage of our work on real life. We were working in a real business and this problem wasted some valuable hours of work, that is OK because we are not paying for support, but is frustrating when you see that others had the same problem, the solution was provided and was rejected.
I don't propose to disable the feature for anyone, just if is not available, and if this can be solved just adding a few lines to check the library version of as the PR did checking if the protocol is available I think must be done...
The change in the PR alone didn't help, that was the problem with the PR :/
But if it works for you, I'll happily re-add the check in another PR - it's not as if I hadn't tried 😅
I asked for #903 because we found the issue looking exactly at that line. Removing ->withProtocolVersion('2.0') solved the problem for us in CentOS 7.9 with PHP 8.1. Downgrading to 7.9.1 fixed the problem too...
#903 doesn't seem to have worked (https://github.com/kreait/firebase-php/issues/888#issuecomment-2144293337). Worse, if it works for you but not @Daniel-Cong, I'm even more inclined to not check this, who knows what else is at play in the multitude of environments that the SDK could be used in 😕
It's not about what we think as open source developers (people must update it's dependencies), it's about the usage of our work on real life. We were working in a real business and this problem wasted some valuable hours of work, that is OK because we are not paying for support, but is frustrating when you see that others had the same problem, the solution was provided and was rejected.
In real life, this should be a paid product and then I would be able to prioritize this.
I do get your point, it is frustrating, but I've spent thousands of hours on the SDK for free and saved other people a magnitude of that cumulated. Then hearing that I'm wasting people's time is frustrating as well and makes me wonder if my time spent on this was a waste.
(I understand my comments on this wasn't what you intended with your original message, and they are not directly directed at you, this isn't the first time I have this discussion, and that's frustrating as well)
#903 doesn't seem to have worked (#888 (comment)). Worse, if it works for you but not @Daniel-Cong, I'm even more inclined to not check this, who knows what else is at play in the multitude of environments that the SDK could be used in 😕
No problem, we will keep the 7.9.1 version and will take a look to understand the code and why this works for us. I will do a PR if I can solve the problem with guarantees and explaining it properly.
Thank you!
I shortly thought about re-releasing 7.9.1 as 7.14.0, adding trying the libcurl check/minimum requirement and then immediately re-releasing 7.13 as 7.14.1, but that feels wrong...
Unfortunately GitHub Runners can not use CentOS as a base image, perhaps a good start for a PR could be to create a custom job that runs the messaging tests within a CentOS docker container 🤔
I shortly thought about re-releasing 7.9.1 as 7.14.0, adding trying the libcurl check/minimum requirement and then immediately re-releasing 7.13 as 7.14.1, but that feels wrong...
If 2.0 protocol is required now and removing the withProtocolVersion('2.0') call causes some problems, why no release a new major version (8.x) with those breaking changes and keep 7.x compatible with 1.1 protocol?.
Anyway, there's no problem for us to force 7.9.1 version until we update our server...