├── CHANGELOG.md ├── LICENSE ├── README.md ├── SECURITY.md ├── composer.json ├── config └── firebase.php └── src ├── Facades └── Firebase.php ├── FirebaseProject.php ├── FirebaseProjectManager.php └── ServiceProvider.php /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ## Unreleased 4 | 5 | ## 6.0.0 - 2025-02-24 6 | 7 | * Added support for Laravel 12 8 | * Dropped support for Laravel 9 and 10 9 | * Dropped support for PHP 8.1 (Laravel 11 requires at least PHP 8.2) 10 | 11 | ## 5.10.0 - 2024-11-22 12 | 13 | * Added support for PHP 8.4 14 | 15 | ## 5.9.1 - 2024-06-23 16 | 17 | * Revert making the Service provider deferrable. The auto discovery problem is hopefully still fixed because of 18 | the change in the latest version of the SDK. 19 | 20 | ## 5.9.0 - 2024-06-23 21 | 22 | * Service Provider Registration is now deferred. This should fix the credentials auto discovery in Laravel's 23 | package discovery stage 24 | ([#210](https://github.com/kreait/laravel-firebase/pull/210)) 25 | 26 | ## 5.8.0 - 2024-03-13 27 | 28 | * Added support for Laravel 11 29 | ([#214](https://github.com/kreait/laravel-firebase/pull/214)) 30 | 31 | ## 5.7.0 - 2024-02-19 32 | 33 | * Enabled using `symfony/cache:^7` 34 | 35 | ## 5.6.0 - 2024-01-13 36 | 37 | * Added support for overriding the name of the Firestore Default Database 38 | ([#209](https://github.com/kreait/laravel-firebase/pull/209)) 39 | 40 | ## 5.5.0 - 2023-11-30 41 | 42 | * Added support for PHP 8.3 43 | 44 | ## 5.4.0 - 2023-10-05 45 | 46 | * Added support for configuration of credentials with a config array 47 | ([#202](https://github.com/kreait/laravel-firebase/pull/202)) 48 | 49 | ## 5.3.0 - 2023-07-26 50 | 51 | * Enabled injecting middlewares into the Firebase API client 52 | ([#187](https://github.com/kreait/laravel-firebase/pull/187)) 53 | 54 | ## 5.2.0 - 2023-03-30 55 | 56 | * Added AppCheck support 57 | ([#174](https://github.com/kreait/laravel-firebase/pull/174)) 58 | 59 | ## 5.1.0 - 2023-02-15 60 | 61 | * Added support for Laravel 10 62 | 63 | ## 5.0.0 - 2023-01-13 64 | 65 | * Upgraded `kreait/firebase-php` from 6.x to 7.x 66 | * Dropped support for PHP <8.1, Laravel <9.0 67 | * Dropped support for Lumen ([it is not recommended anymore to use it](https://github.com/laravel/lumen/commit/69b26578d2f15595ea901278434b74df459c4329)) 68 | * The ability to disable credentials auto-discovery has been removed. If you don't want a service account to be 69 | auto-discovered, provide it by setting the `GOOGLE_APPLICATION_CREDENTIALS` environment variable or by modifying 70 | the package configuration. 71 | 72 | ## 4.2.0 - 2022-07-28 73 | 74 | * Bumped dependencies, the minimum version of the underlying SDK is now 6.7.0. 75 | * Updated comment in `config/firebase.php` to reference the default HTTP timeout 76 | * With `kreait/firebase` 6.7.0, the default was changed from ∞ to 30 seconds. 77 | 78 | ## 4.1.0 - 2022-02-08 79 | 80 | * Added support for Laravel 9 ([#118](https://github.com/kreait/laravel-firebase/pull/118)) 81 | 82 | ## 4.0.0 - 2022-01-09 83 | 84 | This is a release with breaking changes. Please review the following changes and adapt your application where needed. 85 | 86 | ### Changes 87 | 88 | * Added support for `kreait/firebase-php` ^6.0 89 | * Dropped support for `kreait/firebase-php` <6.0 90 | * Dropped support for Laravel/Lumen <8.0 91 | * Removed deprecated Facades - use the `Kreait\Laravel\Firebase\Facades\Firebase` facade instead 92 | * `Kreait\Laravel\Firebase\Facades\FirebaseAuth` 93 | * `Kreait\Laravel\Firebase\Facades\FirebaseDatabase` 94 | * `Kreait\Laravel\Firebase\Facades\FirebaseDynamicLinks` 95 | * `Kreait\Laravel\Firebase\Facades\FirebaseFirestore` 96 | * `Kreait\Laravel\Firebase\Facades\FirebaseMessaging` 97 | * `Kreait\Laravel\Firebase\Facades\FirebaseRemoteConfig` 98 | * `Kreait\Laravel\Firebase\Facades\FirebaseStorage` 99 | * Removed support deprecated config options and environment variables 100 | * `$config['debug']`/`FIREBASE_ENABLE_DEBUG`, use the `http_debug_log_channel` config option instead 101 | 102 | ## 3.4.0 - 2021-12-04 103 | ### Added 104 | * Added support for caching the authentication tokens used for connecting to the Firebase servers. 105 | 106 | ## 3.3.0 - 2021-11-29 107 | ### Added 108 | * Ensure support for all PHP 8.x versions 109 | ([#110](https://github.com/kreait/laravel-firebase/pull/110)) 110 | 111 | ## 3.2.0 - 2021-10-21 112 | ### Added 113 | * Support for Database Auth Variable Overrides 114 | ([#93](https://github.com/kreait/laravel-firebase/pull/93)) 115 | ### Changed 116 | * Type-hints have been updated to point to the interfaces that the underlying SDK provides 117 | since more recent versions. 118 | * Bumped `kreait/firebase-php` dependency to `^5.24` (Database Auth Variable Overrides are supported since `5.22`) 119 | 120 | ## 3.1.0 - 2021-02-03 121 | ### Added 122 | * Support for tenant awareness via `FIREBASE_AUTH_TENANT_ID` environment variable 123 | or `firebase.projects.*.auth.tenant_id` config variable. 124 | ([#79](https://github.com/kreait/laravel-firebase/pull/79)) 125 | (thanks to [@sl0wik](https://github.com/sl0wik)) 126 | 127 | ## 3.0.0 - 2020-11-01 128 | ### Added 129 | * Support for multiple firebase projects (thanks to [@dododedodonl](https://github.com/dododedodonl)). 130 | * `\Kreait\Laravel\Firebase\Facades\Firebase` facade 131 | * HTTP Client Options are now configurable (thanks to [@kakajansh](https://github.com/kakajansh)) 132 | 133 | ### Changed 134 | * [config/firebase.php](config/firebase.php) has a new format to support multiple projects 135 | 136 | ### Deprecated 137 | * Use of `FirebaseAuth`, `FirebaseDatabase`, `FirebaseDynamicLinks`, `FirebaseFirestore`, `FirebaseMessaging`, `FirebaseRemoteConfig` and `FirebaseStorage` facades 138 | 139 | ### Removed 140 | * Dropped support Laravel 5.8 and Lumen 5.8 141 | 142 | ## 2.4.0 - 2020-10-04 143 | 144 | ### Added 145 | * PHP `^8.0` is now an allowed (but untested) PHP version 146 | 147 | ## 2.3.1 - 2020-09-08 148 | 149 | (no changes, I just somehow mis-tagged 2.3.0 🙈) 150 | 151 | ## 2.3.0 - 2020-09-08 152 | 153 | ### Added 154 | * Added support for Laravel 8.x 155 | 156 | ## 2.2.0 - 2020-06-20 157 | 158 | ### Added 159 | * It is now possible to log HTTP requests and responses to the Firebase APIs to existing log channels. 160 | See the "logging" section in [`config/firebase.php`](config/firebase.php) for the configuration 161 | options and the [SDK Logging Documentation](https://firebase-php.readthedocs.io/en/5.5.0/setup.html#logging) 162 | for more information. 163 | ### Changed 164 | * The default branch of the GitHub repository has been renamed from `master` to `main` - 165 | if you're using `dev-master` as a version constraint in your `composer.json`, please 166 | update it to `dev-main`. 167 | 168 | ## 2.1.0 - 2020-05-27 169 | 170 | * Add config option to debug HTTP requests made directly from the SDK. It is disabled by 171 | default and can be enabled with the `FIREBASE_ENABLE_DEBUG=true` environment variable 172 | or by adding `'debug' => true` to `config/firebase.php`. 173 | 174 | ## 2.0.0 - 2020-04-01 175 | 176 | * Update `kreait/firebase` to `^5.0` 177 | 178 | ## 1.5.0 - 2020-02-29 179 | 180 | * Updated `kreait/firebase-php` to `^4.40.1` 181 | * Added support for Laravel/Lumen `^7.0` 182 | 183 | ## 1.4.0 - 2020-02-22 184 | 185 | * Updated `kreait/firebase-php` to `^4.40.0` 186 | * A relative path to a credentials file is now resolved with `base_path()` to address issues on Windows systems [#7](https://github.com/kreait/laravel-firebase/issues/7) 187 | 188 | ## 1.3.0 - 2020-01-15 189 | 190 | * Added a notice about not using the factory pattern described in the SDK documentation when using this package. 191 | (Although not a code change, adding it in the changelog to enhance visibility) 192 | * Added support for [Lumen](https://lumen.laravel.com/) 193 | * Updated `kreait/firebase-php` to `^4.38.1` 194 | 195 | ## 1.2.0 - 2019-10-26 196 | 197 | * Updated `kreait/firebase-php` to `^4.35.0` 198 | * Added Firestore to the Service Provider and as `FirebaseFirestore` facade 199 | 200 | ## 1.1.0 - 2019-09-19 201 | 202 | * Updated `kreait/firebase-php` to `^4.32.0` 203 | * Added Dynamic Links to the Service Provider and as `FirebaseDynamicLinks` facade 204 | * Added `FIREBASE_DYNAMIC_LINKS_DEFAULT_DOMAIN` as environment variable 205 | 206 | To update the package, please re-publish its configuration 207 | 208 | ```bash 209 | php artisan vendor:publish --provider="Kreait\Laravel\Firebase\ServiceProvider" --tag=config 210 | ``` 211 | 212 | or add the following section to `config/firebase.php`: 213 | 214 | ```php 215 | [ 220 | 'default_domain' => env('FIREBASE_DYNAMIC_LINKS_DEFAULT_DOMAIN') 221 | ], 222 | // ... 223 | ]; 224 | ``` 225 | 226 | ## 1.0.1 - 2019-08-19 227 | 228 | * Made clear that this package needs Laravel 5.8 or higher. 229 | * Updated `kreait/firebase-php` to `^4.30.1` 230 | * Required `illuminate/contracts` and `illuminate/support` 231 | 232 | ## 1.0.0 - 2019-08-17 233 | 234 | * Initial release 235 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Jérôme Gamez, https://github.com/jeromegamez 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Firebase for Laravel 2 | 3 | A Laravel package for the [Firebase PHP Admin SDK](https://github.com/kreait/firebase-php). 4 | 5 | [![Current version](https://img.shields.io/packagist/v/kreait/laravel-firebase.svg?logo=composer)](https://packagist.org/packages/kreait/laravel-firebase) 6 | [![Monthly Downloads](https://img.shields.io/packagist/dm/kreait/laravel-firebase.svg)](https://packagist.org/packages/kreait/laravel-firebase/stats) 7 | [![Total Downloads](https://img.shields.io/packagist/dt/kreait/laravel-firebase.svg)](https://packagist.org/packages/kreait/laravel-firebase/stats) 8 | [![Tests](https://github.com/kreait/laravel-firebase/workflows/Tests/badge.svg?branch=main)](https://github.com/kreait/laravel-firebase/actions) 9 | [![codecov](https://codecov.io/gh/kreait/laravel-firebase/branch/main/graph/badge.svg)](https://codecov.io/gh/kreait/laravel-firebase) 10 | [![Sponsor](https://img.shields.io/static/v1?logo=GitHub&label=Sponsor&message=%E2%9D%A4&color=ff69b4)](https://github.com/sponsors/jeromegamez) 11 | 12 | --- 13 | 14 | ## The future of the Firebase Admin PHP SDK 15 | 16 | Please read about the future of the Firebase Admin PHP SDK on the 17 | [SDK's GitHub Repository](https://github.com/kreait/firebase-php). 18 | 19 | --- 20 | 21 | - [Installation](#installation) 22 | - [Laravel](#laravel) 23 | - [Configuration](#configuration) 24 | - [Credentials with JSON files](#credentials-with-json-files) 25 | - [Credentials with Arrays](#credentials-with-arrays) 26 | - [Usage](#usage) 27 | - [Multiple projects](#multiple-projects) 28 | - [Supported Versions](#supported-versions) 29 | - [License](#license) 30 | 31 | ## Installation 32 | 33 | ```bash 34 | composer require kreait/laravel-firebase 35 | ``` 36 | 37 | ## Configuration 38 | 39 | In order to access a Firebase project and its related services using a server SDK, requests must be authenticated. 40 | For server-to-server communication this is done with a Service Account. 41 | 42 | If you don't already have generated a Service Account, you can do so by following the instructions from the 43 | official documentation pages at https://firebase.google.com/docs/admin/setup#initialize_the_sdk_in_non-google_environments. 44 | 45 | Once you have downloaded the Service Account JSON file, you can configure the package by specifying 46 | environment variables starting with `FIREBASE_` in your `.env` file. Usually, the following are 47 | required for the package to work: 48 | 49 | ``` 50 | # You can find the database URL for your project at 51 | # https://console.firebase.google.com/project/_/database 52 | FIREBASE_DATABASE_URL=https://.firebaseio.com 53 | ``` 54 | 55 | For further configuration, please see [config/firebase.php](config/firebase.php). You can modify the configuration 56 | by copying it to your local `config` directory or by defining the environment variables used in the config file: 57 | 58 | ```bash 59 | # Laravel 60 | php artisan vendor:publish --provider="Kreait\Laravel\Firebase\ServiceProvider" --tag=config 61 | ``` 62 | 63 | ### Credentials with JSON files 64 | 65 | The package uses auto discovery for the default project to find the credentials needed for authenticating requests to 66 | the Firebase APIs by inspecting certain environment variables and looking into Google's well known path(s). 67 | 68 | If you don't want a service account to be auto-discovered, provide it by setting the `FIREBASE_CREDENTIALS` or `GOOGLE_APPLICATION_CREDENTIALS` environment variable or by adapting the package configuration, like so for example: 69 | 70 | ```.env 71 | FIREBASE_CREDENTIALS=storage/app/firebase-auth.json 72 | ``` 73 | 74 | ### Credentials with Arrays 75 | 76 | If you prefer to have more control over the configuration items required to configure the credentials, you can also transpose the Service Account JSON file as an array within your `config/firebase.php` file. 77 | 78 | ```php 79 | 'credentials' => [ 80 | 'type' => 'service_account', 81 | 'project_id' => 'some-project-123', 82 | 'private_key_id' => '123456789', 83 | 'private_key' => '-----BEGIN PRIVATE KEY-----\nFOO_BAR_123456789\n-----END PRIVATE KEY-----\n', 84 | 'client_email' => 'firebase-adminsdk-cwiuo@some-project-123.iam.gserviceaccount.com', 85 | 'client_id' => '123456789', 86 | 'auth_uri' => 'https://accounts.google.com/o/oauth2/auth', 87 | 'token_uri' => 'https://oauth2.googleapis.com/token', 88 | 'auth_provider_x509_cert_url' => 'https://www.googleapis.com/oauth2/v1/certs', 89 | 'client_x509_cert_url' => 'https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-cwiuo%40some-project-123.iam.gserviceaccount.com', 90 | 'universe_domain' => 'googleapis.com', 91 | ], 92 | ``` 93 | 94 | ## Usage 95 | 96 | Once you have retrieved a component, please refer to the [documentation of the Firebase PHP Admin SDK](https://firebase-php.readthedocs.io) 97 | for further information on how to use it. 98 | 99 | **You don't need and should not use the `new Factory()` pattern described in the SDK documentation, this is already 100 | done for you with the Laravel Service Provider. Use Dependency Injection, the Facades or the `app()` helper instead** 101 | 102 | ### Multiple projects 103 | 104 | Multiple projects can be configured in [config/firebase.php](config/firebase.php) by adding another section to the projects array. 105 | 106 | When accessing components, the facade uses the default project. You can also explicitly use a project: 107 | 108 | ```php 109 | use Kreait\Laravel\Firebase\Facades\Firebase; 110 | 111 | // Return an instance of the Auth component for the default Firebase project 112 | $defaultAuth = Firebase::auth(); 113 | // Return an instance of the Auth component for a specific Firebase project 114 | $appAuth = Firebase::project('app')->auth(); 115 | $anotherAppAuth = Firebase::project('another-app')->auth(); 116 | ``` 117 | 118 | ## Supported Versions 119 | 120 | **Only the latest version is actively supported.** 121 | 122 | Earlier versions will receive security fixes as long as their **lowest** SDK requirement receives security fixes. You 123 | can find the currently supported versions and support options in the [SDK's README](https://github.com/kreait/firebase-php). 124 | 125 | | Version | Initial Release | Supported SDK Versions | Supported Laravel Versions | Status | 126 | |---------|-----------------|------------------------|----------------------------|--------------| 127 | | `6.x` | 24 Feb 2025 | `^7.0` | `^11.0`, `^12.0` | Active | 128 | | `5.x` | 13 Jan 2023 | `^7.0` | `^9.0`, `^10.0`, `^11.0` | Paid support | 129 | | `4.x` | 09 Jan 2022 | `^6.0` | `^8.0` | End of life | 130 | | `3.x` | 01 Nov 2020 | `^5.24` | `^6.0, ^7.0, ^8.0` | End of life | 131 | | `2.x` | 01 Apr 2020 | `^5.0` | `^5.8, ^6.0, ^7.0, ^8.0` | End of life | 132 | | `1.x` | 17 Aug 2019 | `^4.40.1` | `^5.8, ^6.0, ^7.0` | End of life | 133 | 134 | ## License 135 | 136 | This project is licensed under the [MIT License](LICENSE). 137 | 138 | Your use of Firebase is governed by the [Terms of Service for Firebase Services](https://firebase.google.com/terms/). 139 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Security contact information 2 | 3 | To report a security vulnerability, please use the 4 | [Tidelift security contact](https://tidelift.com/security). 5 | Tidelift will coordinate the fix and disclosure. 6 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kreait/laravel-firebase", 3 | "description": "A Laravel package for the Firebase PHP Admin SDK", 4 | "keywords": ["laravel", "firebase", "firebase", "sdk", "api", "database", "fcm", "gcm"], 5 | "type": "library", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Jérôme Gamez", 10 | "email": "jerome@gamez.name" 11 | } 12 | ], 13 | "require": { 14 | "php": "~8.2.0 || ~8.3.0 || ~8.4.0", 15 | "kreait/firebase-php": "^7.13", 16 | "illuminate/contracts": "^11.0 || ^12.0", 17 | "illuminate/notifications": "^11.0 || ^12.0", 18 | "illuminate/support": "^11.0 || ^12.0", 19 | "symfony/cache": "^6.1.2 || ^7.0.3" 20 | }, 21 | "require-dev": { 22 | "orchestra/testbench": "^9.0 || ^10.0", 23 | "laravel/pint": "^1.14", 24 | "phpunit/phpunit": "^11.4.3" 25 | }, 26 | "autoload": { 27 | "psr-4": { 28 | "Kreait\\Laravel\\Firebase\\": "src" 29 | } 30 | }, 31 | "autoload-dev": { 32 | "psr-4": { 33 | "Kreait\\Laravel\\Firebase\\Tests\\": "tests" 34 | } 35 | }, 36 | "extra": { 37 | "laravel": { 38 | "providers": [ 39 | "Kreait\\Laravel\\Firebase\\ServiceProvider" 40 | ], 41 | "aliases": { 42 | "Firebase": "Kreait\\Laravel\\Firebase\\Facades\\Firebase" 43 | } 44 | } 45 | }, 46 | "scripts": { 47 | "cs": [ 48 | "vendor/bin/pint" 49 | ], 50 | "test": [ 51 | "vendor/bin/phpunit" 52 | ] 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /config/firebase.php: -------------------------------------------------------------------------------- 1 | env('FIREBASE_PROJECT', 'app'), 13 | 14 | /* 15 | * ------------------------------------------------------------------------ 16 | * Firebase project configurations 17 | * ------------------------------------------------------------------------ 18 | */ 19 | 20 | 'projects' => [ 21 | 'app' => [ 22 | 23 | /* 24 | * ------------------------------------------------------------------------ 25 | * Credentials / Service Account 26 | * ------------------------------------------------------------------------ 27 | * 28 | * In order to access a Firebase project and its related services using a 29 | * server SDK, requests must be authenticated. For server-to-server 30 | * communication this is done with a Service Account. 31 | * 32 | * If you don't already have generated a Service Account, you can do so by 33 | * following the instructions from the official documentation pages at 34 | * 35 | * https://firebase.google.com/docs/admin/setup#initialize_the_sdk 36 | * 37 | * Once you have downloaded the Service Account JSON file, you can use it 38 | * to configure the package. 39 | * 40 | * If you don't provide credentials, the Firebase Admin SDK will try to 41 | * auto-discover them 42 | * 43 | * - by checking the environment variable FIREBASE_CREDENTIALS 44 | * - by checking the environment variable GOOGLE_APPLICATION_CREDENTIALS 45 | * - by trying to find Google's well known file 46 | * - by checking if the application is running on GCE/GCP 47 | * 48 | * If no credentials file can be found, an exception will be thrown the 49 | * first time you try to access a component of the Firebase Admin SDK. 50 | * 51 | */ 52 | 53 | 'credentials' => env('FIREBASE_CREDENTIALS', env('GOOGLE_APPLICATION_CREDENTIALS')), 54 | 55 | /* 56 | * ------------------------------------------------------------------------ 57 | * Firebase Auth Component 58 | * ------------------------------------------------------------------------ 59 | */ 60 | 61 | 'auth' => [ 62 | 'tenant_id' => env('FIREBASE_AUTH_TENANT_ID'), 63 | ], 64 | 65 | /* 66 | * ------------------------------------------------------------------------ 67 | * Firestore Component 68 | * ------------------------------------------------------------------------ 69 | */ 70 | 71 | 'firestore' => [ 72 | 73 | /* 74 | * If you want to access a Firestore database other than the default database, 75 | * enter its name here. 76 | * 77 | * By default, the Firestore client will connect to the `(default)` database. 78 | * 79 | * https://firebase.google.com/docs/firestore/manage-databases 80 | */ 81 | 82 | // 'database' => env('FIREBASE_FIRESTORE_DATABASE'), 83 | ], 84 | 85 | /* 86 | * ------------------------------------------------------------------------ 87 | * Firebase Realtime Database 88 | * ------------------------------------------------------------------------ 89 | */ 90 | 91 | 'database' => [ 92 | 93 | /* 94 | * In most of the cases the project ID defined in the credentials file 95 | * determines the URL of your project's Realtime Database. If the 96 | * connection to the Realtime Database fails, you can override 97 | * its URL with the value you see at 98 | * 99 | * https://console.firebase.google.com/u/1/project/_/database 100 | * 101 | * Please make sure that you use a full URL like, for example, 102 | * https://my-project-id.firebaseio.com 103 | */ 104 | 105 | 'url' => env('FIREBASE_DATABASE_URL'), 106 | 107 | /* 108 | * As a best practice, a service should have access to only the resources it needs. 109 | * To get more fine-grained control over the resources a Firebase app instance can access, 110 | * use a unique identifier in your Security Rules to represent your service. 111 | * 112 | * https://firebase.google.com/docs/database/admin/start#authenticate-with-limited-privileges 113 | */ 114 | 115 | // 'auth_variable_override' => [ 116 | // 'uid' => 'my-service-worker' 117 | // ], 118 | 119 | ], 120 | 121 | 'dynamic_links' => [ 122 | 123 | /* 124 | * Dynamic links can be built with any URL prefix registered on 125 | * 126 | * https://console.firebase.google.com/u/1/project/_/durablelinks/links/ 127 | * 128 | * You can define one of those domains as the default for new Dynamic 129 | * Links created within your project. 130 | * 131 | * The value must be a valid domain, for example, 132 | * https://example.page.link 133 | */ 134 | 135 | 'default_domain' => env('FIREBASE_DYNAMIC_LINKS_DEFAULT_DOMAIN'), 136 | ], 137 | 138 | /* 139 | * ------------------------------------------------------------------------ 140 | * Firebase Cloud Storage 141 | * ------------------------------------------------------------------------ 142 | */ 143 | 144 | 'storage' => [ 145 | 146 | /* 147 | * Your project's default storage bucket usually uses the project ID 148 | * as its name. If you have multiple storage buckets and want to 149 | * use another one as the default for your application, you can 150 | * override it here. 151 | */ 152 | 153 | 'default_bucket' => env('FIREBASE_STORAGE_DEFAULT_BUCKET'), 154 | 155 | ], 156 | 157 | /* 158 | * ------------------------------------------------------------------------ 159 | * Caching 160 | * ------------------------------------------------------------------------ 161 | * 162 | * The Firebase Admin SDK can cache some data returned from the Firebase 163 | * API, for example Google's public keys used to verify ID tokens. 164 | * 165 | */ 166 | 167 | 'cache_store' => env('FIREBASE_CACHE_STORE', 'file'), 168 | 169 | /* 170 | * ------------------------------------------------------------------------ 171 | * Logging 172 | * ------------------------------------------------------------------------ 173 | * 174 | * Enable logging of HTTP interaction for insights and/or debugging. 175 | * 176 | * Log channels are defined in config/logging.php 177 | * 178 | * Successful HTTP messages are logged with the log level 'info'. 179 | * Failed HTTP messages are logged with the log level 'notice'. 180 | * 181 | * Note: Using the same channel for simple and debug logs will result in 182 | * two entries per request and response. 183 | */ 184 | 185 | 'logging' => [ 186 | 'http_log_channel' => env('FIREBASE_HTTP_LOG_CHANNEL'), 187 | 'http_debug_log_channel' => env('FIREBASE_HTTP_DEBUG_LOG_CHANNEL'), 188 | ], 189 | 190 | /* 191 | * ------------------------------------------------------------------------ 192 | * HTTP Client Options 193 | * ------------------------------------------------------------------------ 194 | * 195 | * Behavior of the HTTP Client performing the API requests 196 | */ 197 | 198 | 'http_client_options' => [ 199 | 200 | /* 201 | * Use a proxy that all API requests should be passed through. 202 | * (default: none) 203 | */ 204 | 205 | 'proxy' => env('FIREBASE_HTTP_CLIENT_PROXY'), 206 | 207 | /* 208 | * Set the maximum amount of seconds (float) that can pass before 209 | * a request is considered timed out 210 | * 211 | * The default time out can be reviewed at 212 | * https://github.com/kreait/firebase-php/blob/6.x/src/Firebase/Http/HttpClientOptions.php 213 | */ 214 | 215 | 'timeout' => env('FIREBASE_HTTP_CLIENT_TIMEOUT'), 216 | 217 | 'guzzle_middlewares' => [], 218 | ], 219 | ], 220 | ], 221 | ]; 222 | -------------------------------------------------------------------------------- /src/Facades/Firebase.php: -------------------------------------------------------------------------------- 1 | factory = $factory; 42 | $this->config = $config; 43 | } 44 | 45 | public function appCheck(): AppCheck 46 | { 47 | if (! $this->appCheck) { 48 | $this->appCheck = $this->factory->createAppCheck(); 49 | } 50 | 51 | return $this->appCheck; 52 | } 53 | 54 | public function auth(): Auth 55 | { 56 | if (! $this->auth) { 57 | $this->auth = $this->factory->createAuth(); 58 | } 59 | 60 | return $this->auth; 61 | } 62 | 63 | public function database(): Database 64 | { 65 | if (! $this->database) { 66 | $this->database = $this->factory->createDatabase(); 67 | } 68 | 69 | return $this->database; 70 | } 71 | 72 | public function dynamicLinks(): DynamicLinks 73 | { 74 | if (! $this->dynamicLinks) { 75 | $this->dynamicLinks = $this->factory->createDynamicLinksService($this->config['dynamic_links']['default_domain'] ?? null); 76 | } 77 | 78 | return $this->dynamicLinks; 79 | } 80 | 81 | public function firestore(): Firestore 82 | { 83 | if (! $this->firestore) { 84 | $this->firestore = $this->factory->createFirestore(); 85 | } 86 | 87 | return $this->firestore; // @codeCoverageIgnore 88 | } 89 | 90 | public function messaging(): Messaging 91 | { 92 | if (! $this->messaging) { 93 | $this->messaging = $this->factory->createMessaging(); 94 | } 95 | 96 | return $this->messaging; 97 | } 98 | 99 | public function remoteConfig(): RemoteConfig 100 | { 101 | if (! $this->remoteConfig) { 102 | $this->remoteConfig = $this->factory->createRemoteConfig(); 103 | } 104 | 105 | return $this->remoteConfig; 106 | } 107 | 108 | public function storage(): Storage 109 | { 110 | if (! $this->storage) { 111 | $this->storage = $this->factory->createStorage(); 112 | } 113 | 114 | return $this->storage; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/FirebaseProjectManager.php: -------------------------------------------------------------------------------- 1 | app = $app; 26 | } 27 | 28 | public function project(?string $name = null): FirebaseProject 29 | { 30 | $name = $name ?? $this->getDefaultProject(); 31 | 32 | if (! isset($this->projects[$name])) { 33 | $this->projects[$name] = $this->configure($name); 34 | } 35 | 36 | return $this->projects[$name]; 37 | } 38 | 39 | protected function configuration(string $name): array 40 | { 41 | $config = $this->app->config->get('firebase.projects.'.$name); 42 | 43 | if (! $config) { 44 | throw new InvalidArgumentException("Firebase project [{$name}] not configured."); 45 | } 46 | 47 | return $config; 48 | } 49 | 50 | protected function resolveJsonCredentials(string $credentials): string 51 | { 52 | $isJsonString = \str_starts_with($credentials, '{'); 53 | $isAbsoluteLinuxPath = \str_starts_with($credentials, '/'); 54 | $isAbsoluteWindowsPath = \str_contains($credentials, ':\\'); 55 | 56 | $isRelativePath = ! $isJsonString && ! $isAbsoluteLinuxPath && ! $isAbsoluteWindowsPath; 57 | 58 | return $isRelativePath ? $this->app->basePath($credentials) : $credentials; 59 | } 60 | 61 | protected function configure(string $name): FirebaseProject 62 | { 63 | $factory = new Factory; 64 | 65 | $config = $this->configuration($name); 66 | 67 | if ($tenantId = $config['auth']['tenant_id'] ?? null) { 68 | $factory = $factory->withTenantId($tenantId); 69 | } 70 | 71 | if ($credentials = $config['credentials']['file'] ?? ($config['credentials'] ?? null)) { 72 | if (is_string($credentials)) { 73 | $credentials = $this->resolveJsonCredentials($credentials); 74 | } 75 | 76 | $factory = $factory->withServiceAccount($credentials); 77 | } 78 | 79 | if ($databaseUrl = $config['database']['url'] ?? null) { 80 | $factory = $factory->withDatabaseUri($databaseUrl); 81 | } 82 | 83 | if ($authVariableOverride = $config['database']['auth_variable_override'] ?? null) { 84 | $factory = $factory->withDatabaseAuthVariableOverride($authVariableOverride); 85 | } 86 | 87 | if ($firestoreDatabase = $config['firestore']['database'] ?? null) { 88 | $factory = $factory->withFirestoreDatabase($firestoreDatabase); 89 | } 90 | 91 | if ($defaultStorageBucket = $config['storage']['default_bucket'] ?? null) { 92 | $factory = $factory->withDefaultStorageBucket($defaultStorageBucket); 93 | } 94 | 95 | if ($cacheStore = $config['cache_store'] ?? null) { 96 | $cache = $this->app->make('cache')->store($cacheStore); 97 | 98 | if ($cache instanceof CacheInterface) { 99 | $cache = new Psr16Adapter($cache); 100 | } else { 101 | throw new InvalidArgumentException('The cache store must be an instance of a PSR-6 or PSR-16 cache'); 102 | } 103 | 104 | $factory = $factory 105 | ->withVerifierCache($cache) 106 | ->withAuthTokenCache($cache); 107 | } 108 | 109 | if ($logChannel = $config['logging']['http_log_channel'] ?? null) { 110 | $factory = $factory->withHttpLogger( 111 | $this->app->make('log')->channel($logChannel) 112 | ); 113 | } 114 | 115 | if ($logChannel = $config['logging']['http_debug_log_channel'] ?? null) { 116 | $factory = $factory->withHttpDebugLogger( 117 | $this->app->make('log')->channel($logChannel) 118 | ); 119 | } 120 | 121 | $options = HttpClientOptions::default(); 122 | 123 | if ($proxy = $config['http_client_options']['proxy'] ?? null) { 124 | $options = $options->withProxy($proxy); 125 | } 126 | 127 | if ($timeout = $config['http_client_options']['timeout'] ?? null) { 128 | $options = $options->withTimeOut((float) $timeout); 129 | } 130 | 131 | if ($middlewares = $config['http_client_options']['guzzle_middlewares'] ?? null) { 132 | $options = $options->withGuzzleMiddlewares($middlewares); 133 | } 134 | 135 | $factory = $factory->withHttpClientOptions($options); 136 | 137 | return new FirebaseProject($factory, $config); 138 | } 139 | 140 | public function getDefaultProject(): string 141 | { 142 | return $this->app->config->get('firebase.default'); 143 | } 144 | 145 | public function setDefaultProject(string $name): void 146 | { 147 | $this->app->config->set('firebase.default', $name); 148 | } 149 | 150 | public function __call($method, $parameters) 151 | { 152 | // Pass call to default project 153 | return $this->project()->{$method}(...$parameters); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/ServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->runningInConsole()) { 16 | return; 17 | } 18 | // @codeCoverageIgnoreEnd 19 | 20 | $this->publishes([ 21 | __DIR__.'/../config/firebase.php' => $this->app->configPath('firebase.php'), 22 | ], 'config'); 23 | } 24 | 25 | public function register(): void 26 | { 27 | $this->mergeConfigFrom(__DIR__.'/../config/firebase.php', 'firebase'); 28 | 29 | $this->registerManager(); 30 | $this->registerComponents(); 31 | } 32 | 33 | private function registerComponents(): void 34 | { 35 | $this->app->singleton(Firebase\Contract\AppCheck::class, static fn (Container $app) => $app->make(FirebaseProjectManager::class)->project()->appCheck()); 36 | $this->app->alias(Firebase\Contract\AppCheck::class, 'firebase.app_check'); 37 | 38 | $this->app->singleton(Firebase\Contract\Auth::class, static fn (Container $app) => $app->make(FirebaseProjectManager::class)->project()->auth()); 39 | $this->app->alias(Firebase\Contract\Auth::class, 'firebase.auth'); 40 | 41 | $this->app->singleton(Firebase\Contract\Database::class, static fn (Container $app) => $app->make(FirebaseProjectManager::class)->project()->database()); 42 | $this->app->alias(Firebase\Contract\Database::class, 'firebase.database'); 43 | 44 | $this->app->singleton(Firebase\Contract\DynamicLinks::class, static fn (Container $app) => $app->make(FirebaseProjectManager::class)->project()->dynamicLinks()); 45 | $this->app->alias(Firebase\Contract\DynamicLinks::class, 'firebase.dynamic_links'); 46 | 47 | $this->app->singleton(Firebase\Contract\Firestore::class, static fn (Container $app) => $app->make(FirebaseProjectManager::class)->project()->firestore()); 48 | $this->app->alias(Firebase\Contract\Firestore::class, 'firebase.firestore'); 49 | 50 | $this->app->singleton(Firebase\Contract\Messaging::class, static fn (Container $app) => $app->make(FirebaseProjectManager::class)->project()->messaging()); 51 | $this->app->alias(Firebase\Contract\Messaging::class, 'firebase.messaging'); 52 | 53 | $this->app->singleton(Firebase\Contract\RemoteConfig::class, static fn (Container $app) => $app->make(FirebaseProjectManager::class)->project()->remoteConfig()); 54 | $this->app->alias(Firebase\Contract\RemoteConfig::class, 'firebase.remote_config'); 55 | 56 | $this->app->singleton(Firebase\Contract\Storage::class, static fn (Container $app) => $app->make(FirebaseProjectManager::class)->project()->storage()); 57 | $this->app->alias(Firebase\Contract\Storage::class, 'firebase.storage'); 58 | } 59 | 60 | private function registerManager(): void 61 | { 62 | $this->app->singleton(FirebaseProjectManager::class, static fn (Container $app) => new FirebaseProjectManager($app)); 63 | $this->app->alias(FirebaseProjectManager::class, 'firebase.manager'); 64 | } 65 | } 66 | --------------------------------------------------------------------------------