Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 20 additions & 39 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,7 @@ concurrency:

jobs:
test:
name: >
${{ format('PHP {0} - Sf {1} - deps {2} - stab. {3}',
matrix.php-version || 'Ø',
matrix.symfony-require || 'Ø',
matrix.dependencies || 'Ø',
matrix.stability || 'Ø'
) }}
name: ${{ matrix.job-name }}
runs-on: "ubuntu-latest"
env:
SYMFONY_REQUIRE: ${{matrix.symfony-require}}
Expand All @@ -39,38 +33,30 @@ jobs:
strategy:
fail-fast: false
matrix:
php-version:
- "8.1"
- "8.2"
- "8.3"
- "8.4"
- "8.5"
dependencies:
- "highest"
stability:
- "stable"
symfony-require:
- ""
include:
# Test with the lowest set of dependencies
- php-version: "8.1"
dependencies: "lowest"
stability: "stable"

# Test 6.4 LTS
- php-version: "8.5"
# Symfony 6.4 LTS on minimum supported PHP
- php-version: "8.3"
symfony-require: "6.4.*"
dependencies: "highest"
job-name: "PHP 8.3 - Symfony 6.4 LTS"

# Test 7.4 LTS
- php-version: "8.5"
# Symfony 7.4 LTS on minimum supported PHP
- php-version: "8.3"
symfony-require: "7.4.*"
dependencies: "highest"
job-name: "PHP 8.3 - Symfony 7.4 LTS"

# Symfony 8 on supported PHP versions
- php-version: "8.4"
symfony-require: "8.0.*"
job-name: "PHP 8.4 - Symfony 8.0"

# Bleeding edge
- php-version: "8.5"
dependencies: "highest"
stability: "dev"
symfony-require: "8.0.*"
job-name: "PHP 8.5 - Symfony 8.0"

# Forward-compat lane for upcoming Symfony 8.x releases
- php-version: "8.5"
symfony-require: "8.*"
job-name: "PHP 8.5 - Symfony 8.x"

steps:
- name: "Checkout"
Expand All @@ -85,15 +71,10 @@ jobs:
ini-file: "development"
tools: flex

- name: "Enforce using stable dependencies"
run: "composer config minimum-stability stable"
if: "${{ matrix.stability == 'stable' }}"

- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v3"
with:
dependency-versions: "${{ matrix.dependencies }}"
composer-options: "--prefer-dist"

- name: Run test suite on PHP ${{ matrix.php }} and Symfony ${{ matrix.symfony }}
- name: Run test suite
run: ./vendor/bin/phpunit
61 changes: 61 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,67 @@

## [Unreleased]

* Dropped support for PHP versions older than 8.3 to match `kreait/firebase-php` 8.x
* Updated the bundle to support `kreait/firebase-php` 8.x
* Removed Dynamic Links support because it was removed from the Firebase Admin SDK
* Removed HTTP request logger configuration options because the underlying SDK hooks were removed
* Added support for per-project `http_client_options` service configuration
* Fixed project option leakage by isolating project factory instances per configured Firebase project
* Removed the container service `Kreait\Firebase\Factory`

### Migration: HTTP request logging

If you previously used `http_request_logger` or `http_request_debug_logger`,
migrate to a `Kreait\Firebase\Http\HttpClientOptions` service and wire your logging through Guzzle middleware.

```yaml
# config/services.yaml
services:
App\Firebase\HttpClientOptionsFactory: ~

app.firebase.http_client_options:
class: Kreait\Firebase\Http\HttpClientOptions
factory: ['@App\Firebase\HttpClientOptionsFactory', 'create']
```

```php
<?php

namespace App\Firebase;

use Kreait\Firebase\Http\HttpClientOptions;

final class HttpClientOptionsFactory
{
public function __construct(private readonly LoggingMiddleware $loggingMiddleware)
{
}

public function create(): HttpClientOptions
{
return HttpClientOptions::default()
->withGuzzleMiddleware($this->loggingMiddleware);
}
}
```

```yaml
# config/packages/firebase.yaml
kreait_firebase:
projects:
my_project:
http_client_options: 'app.firebase.http_client_options'
```

### Migration: custom DI integrations

If you customized bundle internals with compiler passes or direct container lookups:

* `Kreait\Firebase\Factory` is no longer registered as a container service.
* Project factories are now per project (`kreait_firebase.<project>.project_factory`) instead of using only `Kreait\Firebase\Symfony\Bundle\DependencyInjection\Factory\ProjectFactory`.

If your app modified the `ProjectFactory` definition directly, update your code to target the per-project service id(s).

## [5.7.0]

* Added support for PHP 8.5 and Symfony 8
Expand Down
14 changes: 0 additions & 14 deletions Makefile

This file was deleted.

12 changes: 3 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ The following services will be available for your project:
* `kreait_firebase.my_project.messaging`
* `kreait_firebase.my_project.remote_config`
* `kreait_firebase.my_project.storage`
* `kreait_firebase.my_project.dynamic_links`
* `kreait_firebase.other_project.*`

The following classes will be available for dependency injection if you have configured only one project:
Expand All @@ -90,7 +89,6 @@ The following classes will be available for dependency injection if you have con
* `Kreait\Firebase\Contract\Messaging`
* `Kreait\Firebase\Contract\RemoteConfig`
* `Kreait\Firebase\Contract\Storage`
* `Kreait\Firebase\Contract\DynamicLinks`

To make it easier to use classes via dependency injection in the constructor of a class when multiple projects exist, you can do this in the constructor:

Expand All @@ -101,7 +99,6 @@ To make it easier to use classes via dependency injection in the constructor of
* `Kreait\Firebase\Contract\Messaging $myProjectMessaging`
* `Kreait\Firebase\Contract\RemoteConfig $myProjectRemoteConfig`
* `Kreait\Firebase\Contract\Storage $myProjectStorage`
* `Kreait\Firebase\Contract\DynamicLinks $myProjectDynamicLinks`

### Full

Expand Down Expand Up @@ -133,16 +130,13 @@ kreait_firebase:
database_uri: 'https://my_project.firebaseio.com'
# Optional: Make the client tenant aware
tenant_id: 'tenant-id'
# Optional: Default domain for Dynamic Links
default_dynamic_links_domain: 'https://my_project.page.link'
# Optional: Used to cache Google's public keys.
verifier_cache: null # Example: cache.app
# Optional: Used to cache the authentication tokens for connecting to the Firebase servers.
auth_token_cache: null # Example: cache.app
# If set, logs simple HTTP request and response statuses
http_request_logger: null # Example: monolog.logger.firebase
# If set, logs detailed HTTP request and response statuses
http_request_debug_logger: null # Example: monolog.logger.firebase_debug
# Optional: Service id of Kreait\Firebase\Http\HttpClientOptions
# used to configure the SDK's HTTP client.
http_client_options: null # Example: app.firebase.http_client_options
```

## Documentation
Expand Down
11 changes: 8 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@
}
],
"require": {
"php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0",
"kreait/firebase-php": "^7.24",
"php": "~8.3.0 || ~8.4.0 || ~8.5.0",
"kreait/firebase-php": "^8.1",
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0",
"symfony/cache": "^6.4 || ^7.4 || ^8.0",
"symfony/config": "^6.4 || ^7.4 || ^8.0",
"symfony/dependency-injection": "^6.4 || ^7.4 || ^8.0",
"symfony/http-kernel": "^6.4 || ^7.4 || ^8.0"
},
"require-dev": {
"phpunit/phpunit": "^10.5.58"
"phpunit/phpunit": "^12.5.11"
},
"autoload": {
"psr-4": {
Expand All @@ -45,6 +45,11 @@
"scripts": {
"test": [
"vendor/bin/phpunit"
],
"test:coverage": [
"Composer\\Config::disableProcessTimeout",
"mkdir -p build",
"XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-html=build/coverage"
]
}
}
6 changes: 5 additions & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
beStrictAboutOutputDuringTests="true"
displayDetailsOnAllIssues="true"
bootstrap="vendor/autoload.php"
colors="true"
>
Expand All @@ -11,9 +13,11 @@
</testsuite>
</testsuites>

<source restrictDeprecations="true">
<source ignoreIndirectDeprecations="true">
<include>
<directory>src</directory>
</include>
</source>

<coverage ignoreDeprecatedCodeUnits="true"/>
</phpunit>
15 changes: 3 additions & 12 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,6 @@ public function getConfigTreeBuilder(): TreeBuilder
->defaultNull()
->info('Make the client tenant aware')
->end()
->scalarNode('default_dynamic_links_domain')
->example('https://my-project.page.link')
->info('The default domain for dynamic links')
->end()
->scalarNode('verifier_cache')
->defaultNull()
->example('cache.app')
Expand All @@ -69,15 +65,10 @@ public function getConfigTreeBuilder(): TreeBuilder
->example('cache.app')
->info('Used to cache the authentication tokens for connecting to the Firebase servers.')
->end()
->scalarNode('http_request_logger')
->defaultNull()
->example('monolog.logger.firebase')
->info('If set, logs simple HTTP request and response statuses')
->end()
->scalarNode('http_request_debug_logger')
->scalarNode('http_client_options')
->defaultNull()
->example('monolog.logger.firebase_debug')
->info('If set, logs detailed HTTP request and response statuses')
->example('app.firebase.http_client_options')
->info('Service id of a Kreait\\Firebase\\Http\\HttpClientOptions instance to configure the SDK HTTP client.')
->end()
->end()
->end()
Expand Down
32 changes: 9 additions & 23 deletions src/DependencyInjection/Factory/ProjectFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@

use Kreait\Firebase;
use Kreait\Firebase\Factory;
use Kreait\Firebase\Http\HttpClientOptions;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Log\LoggerInterface;
use Psr\SimpleCache\CacheInterface;
use Symfony\Component\Cache\Adapter\Psr16Adapter;

class ProjectFactory
{
private ?CacheItemPoolInterface $verifierCache = null;
private ?CacheItemPoolInterface $authTokenCache = null;
private ?LoggerInterface $httpRequestLogger = null;
private ?LoggerInterface $httpRequestDebugLogger = null;
private ?HttpClientOptions $httpClientOptions = null;

/**
* @param CacheInterface|CacheItemPoolInterface $verifierCache
Expand All @@ -42,14 +41,9 @@ public function setAuthTokenCache($authTokenCache = null): void
$this->authTokenCache = $authTokenCache;
}

public function setHttpRequestLogger(?LoggerInterface $logger = null): void
public function setHttpClientOptions(?HttpClientOptions $httpClientOptions = null): void
{
$this->httpRequestLogger = $logger;
}

public function setHttpRequestDebugLogger(?LoggerInterface $logger = null): void
{
$this->httpRequestDebugLogger = $logger;
$this->httpClientOptions = $httpClientOptions;
}

public function createAuth(array $config = []): Firebase\Contract\Auth
Expand Down Expand Up @@ -85,12 +79,8 @@ public function createFactory(array $config = []): Factory
$factory = $factory->withAuthTokenCache($this->authTokenCache);
}

if ($this->httpRequestLogger) {
$factory = $factory->withHttpLogger($this->httpRequestLogger);
}

if ($this->httpRequestDebugLogger) {
$factory = $factory->withHttpDebugLogger($this->httpRequestDebugLogger);
if ($this->httpClientOptions) {
$factory = $factory->withHttpClientOptions($this->httpClientOptions);
}

return $factory;
Expand All @@ -101,6 +91,9 @@ public function createDatabase(array $config = []): Firebase\Contract\Database
return $this->createFactory($config)->createDatabase();
}

/**
* @codeCoverageIgnore Firestore needs optional runtime dependencies (incl. gRPC), which are not part of the default test setup.
*/
public function createFirestore(array $config = []): Firebase\Contract\Firestore
{
return $this->createFactory($config)->createFirestore();
Expand All @@ -121,13 +114,6 @@ public function createStorage(array $config = []): Firebase\Contract\Storage
return $this->createFactory($config)->createStorage();
}

public function createDynamicLinksService(array $config = []): Firebase\Contract\DynamicLinks
{
$defaultDynamicLinksDomain = $config['default_dynamic_links_domain'] ?? null;

return $this->createFactory($config)->createDynamicLinksService($defaultDynamicLinksDomain);
}

public function createAppCheck(array $config = []): Firebase\Contract\AppCheck
{
return $this->createFactory($config)->createAppCheck();
Expand Down
Loading