Firebase Admin SDK For PHP
Firebase Admin SDK For PHP
Firebase Admin SDK For PHP
1 User Guide 3
1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.1 Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.2 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.3 Usage examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.4 Issues/Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.5 License . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.6 Contributing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.1 Google Service Account . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.2 Custom Database URI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2.3 Caching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2.4 End User Credentials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2.5 Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3 Cloud Messaging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.3.1 Initializing the Messaging component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.3.2 Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.3.3 Send messages to topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.3.4 Send conditional messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.3.5 Send messages to specific devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.3.6 Send messages to multiple devices (Multicast) . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3.7 Send multiple messages at once . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3.8 Adding a notification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3.9 Adding data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3.10 Changing the message target . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3.11 Adding target platform specific configuration . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.3.12 Adding platform independent FCM options . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.3.13 Using Emojis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.3.14 Sending a fully configured raw message . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.3.15 Validating messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.3.16 Topic management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.3.17 App instance management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.4 Cloud Firestore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.4.1 Initializing the Firestore component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.4.2 Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.5 Cloud Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
i
1.5.1 Initializing the Storage component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.5.2 Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.5.3 Default Storage bucket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.6 Realtime Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.6.1 Initializing the Realtime Database component . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.6.2 Retrieving data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.6.3 Saving data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
1.6.4 Database transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.6.5 Debugging API exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.6.6 Database rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
1.7 Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
1.7.1 Initializing the Auth component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
1.7.2 Create custom tokens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
1.7.3 Verify a Firebase ID Token . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1.7.4 Custom Authentication Flows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
1.7.5 Invalidate user sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
1.8 User management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
1.8.1 User Records . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
1.8.2 List users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
1.8.3 Get information about a specific user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
1.8.4 Create a user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
1.8.5 Update a user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
1.8.6 Change a user’s password . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
1.8.7 Change a user’s email . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
1.8.8 Disable a user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
1.8.9 Enable a user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
1.8.10 Custom user claims . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
1.8.11 Delete a user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
1.8.12 Using Email Action Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
1.9 Dynamic Links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
1.9.1 Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
1.9.2 Initializing the Dynamic Links component . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
1.9.3 Create a Dynamic Link . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
1.9.4 Create a short link from a long link . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
1.9.5 Get link statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
1.9.6 Advanced usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
1.10 Remote Config . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
1.10.1 Before you begin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
1.10.2 Initializing the Realtime Database component . . . . . . . . . . . . . . . . . . . . . . . . . 47
1.10.3 Get the Remote Config . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
1.10.4 Create a new Remote Config . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
1.10.5 Add a condition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
1.10.6 Add a parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
1.10.7 Conditional values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
1.10.8 Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
1.10.9 Publish the Remote Config . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
1.10.10 Remote Config history . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
1.11 Framework Integrations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
1.11.1 Laravel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
1.11.2 Symfony . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
1.11.3 CodeIgniter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
1.12 Tutorials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
1.12.1 Articles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
1.12.2 Videos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
ii
1.13 Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
1.13.1 Call to private method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
1.13.2 PHP Parse Error/PHP Syntax Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
1.13.3 Class ‘Kreait\Firebase\ . . . ’ not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
1.13.4 Call to undefined function openssl_sign() . . . . . . . . . . . . . . . . . . . . . . . . 52
1.13.5 cURL error XX: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
1.13.6 ID Tokens are issued in the future . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
1.13.7 “403 Forbidden” Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
1.13.8 MultiCast SendReports are empty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
1.13.9 Proxy configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
1.13.10 Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
iii
iv
Firebase Admin SDK for PHP
Note: If you are interested in using the PHP Admin SDK as a client for end-user access (for example, in a web
application), as opposed to admin access from a privileged environment (like a server), you should instead follow the
instructions for setting up the client JavaScript SDK.
Contents 1
Firebase Admin SDK for PHP
2 Contents
CHAPTER 1
User Guide
1.1 Overview
1.1.1 Requirements
1.1.2 Installation
The recommended way to install the Firebase Admin SDK is with Composer. Composer is a dependency management
tool for PHP that allows you to declare the dependencies your project needs and installs them into your project.
If you want to use the SDK within a Framework, please follow the installation instructions here:
• Laravel: kreait/laravel-firebase
• Symfony: kreait/firebase-bundle
Alternatively, you can specify the Firebase Admin SDK as a dependency in your project’s existing composer.json file:
{
"require": {
"kreait/firebase-php": "^5.0"
}
}
3
Firebase Admin SDK for PHP
<?php
require __DIR__.'/vendor/autoload.php';
You can find out more on how to install Composer, configure autoloading, and other best-practices for defining depen-
dencies at getcomposer.org.
Please continue to the Setup section to learn more about connecting your application to Firebase.
You can find usage examples at https://github.com/jeromegamez/firebase-php-examples and in the tests directory of
this project’s GitHub repository.
1.1.4 Issues/Support
• For bugs, feature requests and past issues: Github issue tracker
• For help with and discussion about the PHP SDK: Discord channel dedicated to this library
• For questions about Firebase in general: Stack Overflow and the Firebase Slack Community.
1.1.5 License
1.1.6 Contributing
Guidelines
3. All pull requests must include unit tests to ensure the change works as expected and to prevent regressions.
The SDK is unit tested with PHPUnit. Run the tests using the Makefile:
make tests
Coding standards
The SDK uses the PHP Coding Standars Fixer to ensure a uniform coding style. Apply coding standard fixed using
the Makefile:
make cs
1.2 Setup
In order to access a Firebase project using a server SDK, you must authenticate your requests to Firebase with a
Service Account.
Follow the steps described in the official Firebase documentation to create a Service Account for your Firebase appli-
cation: Add the Firebase Admin SDK to your Server.
You can then configure the SDK to use this Service Account:
With the SDK
use Kreait\Firebase\Factory;
With autodiscovery
The SDK is able to autodiscover the Service Account for your project in the following conditions:
1. Your application runs on Google Cloud Engine.
2. The path to the JSON key file is defined in one of the following environment variables
• FIREBASE_CREDENTIALS
• GOOGLE_APPLICATION_CREDENTIALS
3. The JSON Key file is located in Google’s “well known path”
1.2. Setup 5
Firebase Admin SDK for PHP
• on Linux/MacOS: $HOME/.config/gcloud/application_default_credentials.json
• on Windows: $APPDATA/gcloud/application_default_credentials.json
If you want to use autodiscovery, a Service Account must not be explicitly configured.
If the project ID in the JSON file does not match the URL of your Firebase application, or if you want to be explicit,
you can configure the Factory like this:
use Kreait\Firebase\Factory;
1.2.3 Caching
Authentication tokens
Before connecting to the Firebase APIs, the SDK fetches an authentication token for your credentials. This authenti-
cation token is cached in-memory so that it can be re-used during the same process.
If you want to cache authentication tokens more effectively, you can provide any implementation of psr/cache to the
Firebase factory when creating your Firebase instance.
Note: Authentication tokens are cached in-memory by default. For Symfony and Laravel, the Framework’s cache
will automatically be used.
For Symfony and Laravel, the Framework’s cache will automatically be used.
Here is an example using the Symfony Cache Component:
use Symfony\Component\Cache\Simple\FilesystemCache;
ID Token Verification
In order to verify ID tokens, the verifier makes a call to fetch Firebase’s currently available public keys. The keys are
cached in memory by default.
If you want to cache the public keys more effectively, you can provide any implementation of psr/simple-cache to the
Firebase factory when creating your Firebase instance.
Note: Public keys tokens are cached in-memory by default. For Symfony and Laravel, the Framework’s cache will
automatically be used.
use Symfony\Component\Cache\Simple\FilesystemCache;
Note: While theoretically possible, it’s not recommended to use end user credentials in the context of a Server-to-
Server backend application.
When using End User Credentials (for example if you set you application default credentials locally with gcloud
auth application-default login), you need to provide the ID of the project you want to access directly
and suppress warnings triggered by the Google Auth Component:
use Kreait\Firebase\Factory;
putenv('SUPPRESS_GCLOUD_CREDS_WARNING=true');
1.2.5 Logging
In order to log API requests to the Firebase APIs, you can provide the factory with loggers implementing
Psr\Log\LoggerInterface.
The following examples use the Monolog logger, but work with any PSR-3 log implementation.
use GuzzleHttp\MessageFormatter;
use Kreait\Firebase\Factory;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// Without further arguments, requests and responses will be logged with basic
// request and response information. Successful responses will be logged with
// the 'info' log level, failures (Status code >= 400) with 'notice'
$factory = $factory->withHttpLogger($httpLogger);
// You can configure the message format and log levels individually
$messageFormatter = new MessageFormatter(MessageFormatter::SHORT);
$factory = $factory->withHttpLogger(
$httpLogger, $messageFormatter, $successes = 'debug', $errors = 'warning'
);
// You can provide a separate logger for detailed HTTP message logs
$httpDebugLogger = new Logger('firebase_http_debug_logs');
$httpDebugLogger->pushHandler(
new StreamHandler('path/to/firebase_api_debug.log',
Logger::DEBUG)
(continues on next page)
1.2. Setup 7
Firebase Admin SDK for PHP
// Logs will include the full request and response headers and bodies
$factory = $factory->withHttpDebugLogger($httpDebugLogger)
You can use the Firebase Admin SDK for PHP to send Firebase Cloud Messaging messages to end-user devices.
Specifically, you can send messages to individual devices, named topics, or condition statements that match one or
more topics.
Note: Sending messages to Device Groups is only possible with legacy protocols which are not supported by this
SDK.
Before you start, please read about Firebase Remote Config in the official documentation:
• Introduction to Firebase Cloud Messaging
• Introduction to Admin FCM API
$messaging = $factory->createMessaging();
use Kreait\Firebase\Messaging;
class MyService
{
public function __construct(Messaging $messaging)
{
$this->messaging = $messaging;
}
}
$messaging = app('firebase.messaging');
use Kreait\Firebase\Messaging\CloudMessage;
$messaging->send($message);
Note: If you notice that a field is not supported by the SDK yet, please open an issue on the issue tracker, so that
others can benefit from it as well.
Based on the publish/subscribe model, FCM topic messaging allows you to send a message to multiple devices that
have opted in to a particular topic. You compose topic messages as needed, and FCM handles routing and delivering
the message reliably to the right devices.
For example, users of a local weather forecasting app could opt in to a “severe weather alerts” topic and receive
notifications of storms threatening specified areas. Users of a sports app could subscribe to automatic updates in live
game scores for their favorite teams.
Some things to keep in mind about topics:
• Topic messaging supports unlimited topics and subscriptions for each app.
• Topic messaging is best suited for content such as news, weather, or other publicly available information.
• Topic messages are optimized for throughput rather than latency. For fast, secure delivery to single devices or
small groups of devices, target messages to registration tokens, not topics.
You can create a message to a topic in one of the following ways:
use Kreait\Firebase\Messaging\CloudMessage;
$topic = 'a-topic';
$message = CloudMessage::fromArray([
'topic' => $topic,
'notification' => [/* Notification data as array */], // optional
'data' => [/* data array */], // optional
]);
$messaging->send($message);
Warning: OR-conditions are currently not processed correctly by the Firebase Rest API, leading to undelivered
messages. This can be resolved by splitting up a message to an OR-condition into multiple messages to AND-
conditions. So one conditional message to 'a' in topics || 'b' in topics should be sent as two
messages to the conditions 'a' in topics && !('b' in topics) and 'b' in topics && !('a'
in topics)
References:
• https://github.com/firebase/quickstart-js/issues/183
• https://stackoverflow.com/a/52302136/284325
Sometimes you want to send a message to a combination of topics. This is done by specifying a condition, which is a
boolean expression that specifies the target topics. For example, the following condition will send messages to devices
that are subscribed to TopicA and either TopicB or TopicC:
"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"
FCM first evaluates any conditions in parentheses, and then evaluates the expression from left to right. In the above
expression, a user subscribed to any single topic does not receive the message. Likewise, a user who does not subscribe
to TopicA does not receive the message. These combinations do receive it:
• TopicA and TopicB
• TopicA and TopicC
use Kreait\Firebase\Messaging\CloudMessage;
$message = CloudMessage::fromArray([
'condition' => $condition,
'notification' => [/* Notification data as array */], // optional
'data' => [/* data array */], // optional
]);
$messaging->send($message);
The Admin FCM API allows you to send messages to individual devices by specifying a registration token for the
target device. Registration tokens are strings generated by the client FCM SDKs for each end-user client app instance.
Each of the Firebase client SDKs are able to generate these registration tokens: iOS, Android, Web, C++, and Unity.
use Kreait\Firebase\Messaging\CloudMessage;
$deviceToken = '...';
$message = CloudMessage::fromArray([
'token' => $deviceToken,
'notification' => [/* Notification data as array */], // optional
'data' => [/* data array */], // optional
]);
$messaging->send($message);
use Kreait\Firebase\Messaging\CloudMessage;
if ($report->hasFailures()) {
foreach ($report->failures()->getItems() as $failure) {
echo $failure->error()->getMessage().PHP_EOL;
}
}
You can send send up to 500 prepared messages (each message has a token, topic or condition as a target) in one go:
use ;
$messages = [
// Up to 500 items, either objects implementing Kreait\Firebase\Messaging\Message
// or arrays that can be used to create valid to
˓→Kreait\Firebase\Messaging\Cloudmessage instances
];
$notification = Notification::fromArray([
'title' => $title,
'body' => $body,
'image' => $imageUrl,
]);
$changedNotification = $notification
->withTitle('Changed title')
->withBody('Changed body')
->withImageUrl('http://lorempixel.com/200/400/');
Once you have created a message with one of the methods described below, you can attach the notification to it:
$message = $message->withNotification($notification);
The data attached to a message must be an array of key-value pairs where all keys and values are strings.
Once you have created a message with one of the methods described below, you can attach data to it:
$data = [
'first_key' => 'First Value',
'second_key' => 'Second Value',
];
$message = $message->withData($data);
You can change the target of an already created message with the withChangedTarget() method.
use Kreait\Firebase\Messaging\CloudMessage;
$deviceToken = '...';
$anotherDeviceToken = '...';
(continues on next page)
$messaging->send($message);
$sameMessageToDifferentTarget = $message->withChangedTarget('token',
˓→$anotherDeviceToken);
Android
You can find the full Android configuration reference in the official documentation: REST Resource:
projects.messages.AndroidConfig
use Kreait\Firebase\Messaging\AndroidConfig;
$config = AndroidConfig::fromArray([
'ttl' => '3600s',
'priority' => 'normal',
'notification' => [
'title' => '$GOOG up 1.43% on the day',
'body' => '$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.
˓→',
$message = $message->withAndroidConfig($config);
APNs
You can find the full APNs configuration reference in the official documentation: REST Resource:
projects.messages.ApnsConfig
use Kreait\Firebase\Messaging\ApnsConfig;
$config = ApnsConfig::fromArray([
'headers' => [
'apns-priority' => '10',
],
'payload' => [
'aps' => [
(continues on next page)
],
'badge' => 42,
],
],
]);
$message = $message->withApnsConfig($config);
WebPush
You can find the full WebPush configuration reference in the official documentation: REST Resource:
projects.messages.Webpush
use Kreait\Firebase\Messaging\WebPushConfig;
$config = WebPushConfig::fromArray([
'notification' => [
'title' => '$GOOG up 1.43% on the day',
'body' => '$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.
˓→',
$message = $message->withWebPushConfig($config);
You can find the full FCM Options configuration reference in the official documentation: REST Resource:
projects.messages.fcm_options
use Kreait\Firebase\Messaging\FcmOptions;
$fcmOptions = FcmOptions::create()
->withAnalyticsLabel('my-analytics-label');
// or
$fcmOptions = [
'analytics_label' => 'my-analytics-label';
];
$message = $message->withFcmOptions($fcmOptions);
Note: You can find a full list of all currently available Emojis at https://www.unicode.org/emoji/charts/full-emoji-list.
html
// You can copy and paste an emoji directly into you source code
$text = "This is an emoji ";
use Kreait\Firebase\Messaging\RawMessageFromArray;
'headers' => [
'apns-priority' => '10',
],
'payload' => [
'aps' => [
(continues on next page)
'notification' => [
'title' => '$GOOG up 1.43% on the day',
'body' => '$GOOG gained 11.80 points to close at 835.67, up 1.43% on
˓→the day.',
$messaging->send($message);
You can validate a message by sending a validation-only request to the Firebase REST API. If the message is invalid, a
KreaitFirebaseExceptionMessagingInvalidMessage exception is thrown, which you can catch to evaluate the raw error
message(s) that the API returned.
use Kreait\Firebase\Exception\Messaging\InvalidMessage;
try {
$messaging->validate($message);
} catch (InvalidMessage $e) {
print_r($e->errors());
}
Subscribe to a topic
You can subscribe one or multiple devices to a topic by passing registration tokens to the subscribeToTopic()
method.
$topic = 'my-topic';
$registrationTokens = [
// ...
};
(continues on next page)
$messaging->subscribeToTopic($topic, $registrationTokens);
Note: You can subscribe up to 1,000 devices in a single request. If you provide an array with over 1,000 registration
tokens, the operation will fail with an error.
You can unsubscribe one or multiple devices from a topic by passing registration tokens to the
unsubscribeFromTopic() method.
$topic = 'my-topic';
$registrationTokens = [
// ...
};
$messaging->unsubscribeFromTopic($topic, $registrationTokens);
Note: You can unsubscribe up to 1,000 devices in a single request. If you provide an array with over 1,000 registration
tokens, the operation will fail with an error.
A registration token is related to an application that generated it. You can retrieve current information about an app
instance by passing a registration token to the getAppInstance() method.
$registrationToken = '...';
$appInstance = $messaging->getAppInstance($registrationToken);
// Return the full information as provided by the Firebase API
$instanceInfo = $appInstance->rawData();
Note: As the data returned by the Google Instance ID API can return differently formed results depending on the
application or platform, it is currently difficult to add reliable convenience methods for specific fields in the raw data.
You can retrieve all topic subscriptions for an app instance with the topicSubscriptions() method:
This SDK provides a bridge to the google/cloud-firestore package. You can enable the component in the SDK by
adding the package to your project dependencies:
Alternatively, you can specify the package as a dependency in your project’s existing composer.json file:
{
"require": {
"google/cloud-firestore": "^1.8",
"kreait/firebase-php": "^4.33"
}
}
Note: The google/cloud-firestore package requires the gRPC PHP extension to be installed. You can find
installation instructions for gRPC at github.com/grpc/grpc. The following projects aim to provide support for Firestore
without the need to install the gRPC PHP extension, but have to be set up separately:
• ahsankhatri/firestore-php
• morrislaptop/firestore-php
Before you start, please read about Firestore in the official documentation:
• Official Documentation
• google/cloud-firestore on GitHub
• PHP API Documentation
• PHP Usage Examples
$firestore = $factory->createFirestore();
use Kreait\Firebase\Firestore;
class MyService
{
public function __construct(Firestore $firestore)
{
$this->firestore = $firestore;
}
}
$firestore = app('firebase.firestore');
$database = $firestore->database();
Cloud Storage for Firebase stores your data in Google Cloud Storage, an exabyte scale object storage solution with
high availability and global redundancy.
This SDK provides a bridge to the google/cloud-storage package. You can enable the component in the SDK by adding
the package to your project dependencies:
Before you start, please read about Firebase Cloud Storage in the official documentation:
• Firebase Cloud Storage
• Introduction to the Admin Cloud Storage API
• PHP API Documentation
• PHP Usage examples
$storage = $factory->createStorage();
use Kreait\Firebase\Storage;
class MyService
{
public function __construct(Storage $storage)
{
$this->storage = $storage;
}
}
$storage = app('firebase.storage');
$storageClient = $storage->getStorageClient();
$defaultBucket = $storage->getBucket();
$anotherBucket = $storage->getBucket('another-bucket');
Note: It is not necessary to change the default storage bucket in most cases.
The SDK assumes that your project’s default storage bucket name has the format <project-id>.appspot.com
and will configure the storage instance accordingly.
If you want to change the default bucket your instance works with, you can specify the name when using the factory:
use Kreait\Firebase\Factory;
Note: The Realtime Database API currently does not support realtime event listeners.
$database = $factory->createDatabase();
use Kreait\Firebase\Database;
class MyService
{
public function __construct(Database $database)
{
$this->database = $database;
}
}
$database = app('firebase.database');
$reference = $database->getReference('path/to/child/location');
Note: Creating a reference does not result in a request to your Database. Requests to your Firebase applications are
executed with the getSnapshot() and getValue() methods only.
You can then retrieve a Database Snapshot for the Reference or its value directly:
$snapshot = $reference->getSnapshot();
$value = $snapshot->getValue();
// or
$value = $reference->getValue();
Database Snapshots
Database Snapshots are immutable copies of the data at a Firebase Database location at the time of a query. The can’t
be modified and will never change.
$snapshot = $reference->getSnapshot();
$value = $snapshot->getValue();
Snapshots provide additional methods to work with and analyze the contained value:
• exists() returns true if the Snapshot contains any (non-null) data.
• getChild() returns another Snapshot for the location at the specified relative path.
• getKey() returns the key (last part of the path) of the location of the Snapshot.
• getReference() returns the Reference for the location that generated this Snapshot.
• getValue() returns the data contained in this Snapshot.
• hasChild() returns true if the specified child path has (non-null) data.
• hasChildren() returns true if the Snapshot has any child properties, i.e. if the value is an array.
• numChildren() returns the number of child properties of this Snapshot, if there are any.
Queries
You can use Queries to filter and order the results returned from the Realtime Database. Queries behave exactly like
References. That means you can execute any method on a Query that you can execute on a Reference.
Note: You can combine every filter query with every order query, but not multiple queries of each type. Shallow
queries are a special case: they can not be combined with any other query method.
Shallow queries
This is an advanced feature, designed to help you work with large datasets without needing to download everything.
Set this to true to limit the depth of the data returned at a location. If the data at the location is a JSON primitive
(string, number or boolean), its value will simply be returned.
If the data snapshot at the location is a JSON object, the values for each key will be truncated to true.
Detailed information can be found on the official Firebase documentation page for shallow queries
$database->getReference('currencies')
// order the reference's children by their key in ascending order
->shallow()
->getSnapshot();
Ordering data
By key
$database->getReference('currencies')
// order the reference's children by their key in ascending order
->orderByKey()
->getSnapshot();
By value
Note: In order to order by value, you must define an index, otherwise the Firebase API will refuse the query.
{
"currencies": {
".indexOn": ".value"
}
}
$database->getReference('currencies')
// order the reference's children by their value in ascending order
->orderByValue()
->getSnapshot();
By child
Note: In order to order by a child value, you must define an index, otherwise the Firebase API will refuse the query.
{
"people": {
".indexOn": "height"
}
}
$database->getReference('people')
// order the reference's children by the values in the field 'height' in
˓→ascending order
->orderByChild('height')
->getSnapshot();
Filtering data
limitToFirst
$database->getReference('people')
// order the reference's children by the values in the field 'height'
->orderByChild('height')
// limits the result to the first 10 children (in this case: the 10 shortest
˓→persons)
limitToLast
$database->getReference('people')
// order the reference's children by the values in the field 'height'
->orderByChild('height')
// limits the result to the last 10 children (in this case: the 10 tallest
˓→persons)
->limitToLast(10)
->getSnapshot();
startAt
$database->getReference('people')
// order the reference's children by the values in the field 'height'
->orderByChild('height')
// returns all persons taller than or exactly 1.68 (meters)
->startAt(1.68)
->getSnapshot();
endAt
$database->getReference('people')
// order the reference's children by the values in the field 'height'
->orderByChild('height')
// returns all persons shorter than or exactly 1.98 (meters)
->endAt(1.98)
->getSnapshot();
equalTo
$database->getReference('people')
// order the reference's children by the values in the field 'height'
->orderByChild('height')
// returns all persons being exactly 1.98 (meters) tall
->equalTo(1.98)
->getSnapshot();
Set/replace values
For basic write operations, you can use set() to save data to a specified reference, replacing any existing data at that
path. For example a configuration array for a website might be set as follows:
$database->getReference('config/website')
->set([
'name' => 'My Application',
'emails' => [
'support' => '[email protected]',
'sales' => '[email protected]',
],
'website' => 'https://app.domain.tld',
]);
$database->getReference('config/website/name')->set('New name');
Note: Using set() overwrites data at the specified location, including any child nodes.
To simultaneously write to specific children of a node without overwriting other child nodes, use the update() method.
When calling update(), you can update lower-level child values by specifying a path for the key. If data is stored
in multiple locations to scale better, you can update all instances of that data using data fan-out.
For example, in a blogging app you might want to add a post and simultaneously update it to the recent activity feed
and the posting user’s activity feed using code like this:
$uid = 'some-user-id';
$postData = [
'title' => 'My awesome post title',
'body' => 'This text should be longer',
];
$updates = [
'posts/'.$newPostKey => $postData,
'user-posts/'.$uid.'/'.$newPostKey => $postData,
];
Writing lists
Use the push() method to append data to a list in multiuser applications. The push() method generates a unique
key every time a new child is added to the specified Firebase reference. By using these auto-generated keys for each
new element in the list, several clients can add children to the same location at the same time without write conflicts.
The unique key generated by push() is based on a timestamp, so list items are automatically ordered chronologically.
You can use the reference to the new data returned by the push() method to get the value of the child’s auto-generated
key or set data for the child. The getKey() method of a push() reference contains the auto-generated key.
$postData = [...];
$postRef = $database->getReference('posts')->push($postData);
Server values
Server values can be written at a location using a placeholder value which is an object with a single .sv key. The
value for that key is the type of server value you wish to set.
Firebase currently supports only one server value: timestamp. You can either set it manually in your write operation,
or use a constant from the Firebase\Database class.
The following to usages are equivalent:
$ref = $database->getReference('posts/my-post')
->set('created_at', ['.sv' => 'timestamp']);
$ref = $database->getReference('posts/my-post')
->set('created_at', Database::SERVER_TIMESTAMP);
Delete data
You can delete a reference, including all data it contains, with the remove() method:
$database->getReference('posts')->remove();
You can also delete by specifying null as the value for another write operation such as set() or update().
$database->getReference('posts')->set(null);
You can use this technique with update() to delete multiple children in a single API call.
Note: Support for database transactions has been added in release 4.21.0
You can use transaction to update data according to its existing state. For example, if you want to increase an upvote
counter, and want to make sure the count accurately reflects multiple, simultaneous upvotes, use a transaction to write
the new value to the counter. Instead of two writes that change the counter to the same number, one of the write
requests fails and you can then retry the request with the new value.
use Kreait\Firebase\Database\Transaction;
$counterRef = $database->getReference('counter');
return $newCounter;
});
Likewise, you can wrap the removal of a reference in a transaction as well: you can remove the reference only if it
hasn’t changed in the meantime.
use Kreait\Firebase\Database\Transaction;
$toBeDeleted = $database->getReference('to-be-deleted');
$transaction->snapshot($toBeDeleted);
If you haven’t snapshotted a reference before trying to change it, the operation will fail with a
\Kreait\Firebase\Exception\Database\ReferenceHasNotBeenSnapshotted error.
If the reference has changed in the Realtime Database after you started the transaction, the transaction will fail with a
\Kreait\Firebase\Exception\Database\TransactionFailed error.
use Kreait\Firebase\Database\Transaction;
use Kreait\Firebase\Exception\Database\ReferenceHasNotBeenSnapshotted;
use Kreait\Firebase\Exception\Database\TransactionFailed;
$ref = $database->getReference('my-ref');
try {
$database->runTransaction(function (Transaction $transaction) use ($ref) {
// $transaction->snapshot($ref);
$referenceInQuestion = $e->getReference();
$referenceInQuestion = $e->getReference();
$failedRequest = $e->getRequest();
$failureResponse = $e->getResponse();
When a request to Firebase fails, the SDK will throw a \Kreait\Firebase\Exception\ApiException that
includes the sent request and the received response object:
try {
$database->getReference('forbidden')->getValue();
} catch (ApiException $e) {
/** @var \Psr\Http\Message\RequestInterface $request */
$request = $e->getRequest();
(continues on next page)
echo $request->getUri().PHP_EOL;
echo $request->getBody().PHP_EOL;
if ($response) {
echo $response->getBody();
}
}
Learn more about the usage of Firebase Realtime Database Rules in the official documentation.
use Kreait\Firebase\Database\RuleSet;
// The default rules allow full read and write access to authenticated users of your
˓→app
$ruleSet = RuleSet::default();
// This level of access means anyone can read or write to your database. You should
// configure more secure rules before launching your app.
$ruleSet = RuleSet::public();
// Private rules disable read and write access to your database by users.
// With these rules, you can only access the database through the
// Firebase console and the Admin SDKs.
$ruleSet = RuleSet::private();
$database->updateRules($ruleSet);
1.7 Authentication
Before you start, please read about Firebase Authentication in the official documentation:
• Introduction to the Admin Database API
• Create custom tokens
1.7. Authentication 29
Firebase Admin SDK for PHP
• Verify ID Tokens
• Revoke refresh tokens
Before you can access the Firebase Realtime Database from a server using the Firebase Admin SDK, you must authen-
ticate your server with Firebase. When you authenticate a server, rather than sign in with a user account’s credentials
as you would in a client app, you authenticate with a service account which identifies your server to Firebase.
You can get two different levels of access when you authenticate using the Firebase Admin SDK:
Administrative privileges: Complete read and write access to a project’s Realtime Database. Use with caution to
complete administrative tasks such as data migration or restructuring that require unrestricted access to your project’s
resources.
Limited privileges: Access to a project’s Realtime Database, limited to only the resources your server needs. Use
this level to complete administrative tasks that have well-defined access requirements. For example, when running
a summarization job that reads data across the entire database, you can protect against accidental writes by setting a
read-only security rule and then initializing the Admin SDK with privileges limited by that rule.
$auth = $factory->createAuth();
use Kreait\Firebase\Auth;
class MyService
{
public function __construct(Auth $auth)
{
$this->auth = $auth;
}
}
$auth = app('firebase.auth');
The Firebase Admin SDK has a built-in method for creating custom tokens. At a minimum, you need to provide a uid,
which can be any string but should uniquely identify the user or device you are authenticating. These tokens expire
after one hour.
$uid = 'some-uid';
$customToken = $auth->createCustomToken($uid);
You can also optionally specify additional claims to be included in the custom token. For example, below, a premiu-
mAccount field has been added to the custom token, which will be available in the auth / request.auth objects in your
Security Rules:
$uid = 'some-uid';
$additionalClaims = [
'premiumAccount' => true
];
Note: This library uses lcobucci/jwt to work with JSON Web Tokens (JWT). You can find the usage instructions at
https://github.com/lcobucci/jwt/blob/3.2/README.md.
If a Firebase client app communicates with your server, you might need to identify the currently signed-in user. To do
so, verify the integrity and authenticity of the ID token and retrieve the uid from it. You can use the uid transmitted in
this way to securely identify the currently signed-in user on your server.
Note: Many use cases for verifying ID tokens on the server can be accomplished by using Security Rules for the
Firebase Realtime Database and Cloud Storage. See if those solve your problem before verifying ID tokens yourself.
Warning: The ID token verification methods included in the Firebase Admin SDKs are meant to verify ID tokens
that come from the client SDKs, not the custom tokens that you create with the Admin SDKs. See Auth tokens for
more information.
use Firebase\Auth\Token\Exception\InvalidToken;
$idTokenString = '...';
try {
$verifiedIdToken = $auth->verifyIdToken($idTokenString);
} catch (\InvalidArgumentException $e) {
echo 'The token could not be parsed: '.$e->getMessage();
} catch (InvalidToken $e) {
echo 'The token is invalid: '.$e->getMessage();
}
$uid = $verifiedIdToken->getClaim('sub');
$user = $auth->getUser($uid);
1.7. Authentication 31
Firebase Admin SDK for PHP
Note: A leeway of 5 minutes is applied when verifying time based claims starting with release 4.25.0
Note: This library uses lcobucci/jwt to work with JSON Web Tokens (JWT). You can find the usage instructions at
https://github.com/lcobucci/jwt/blob/3.2/README.md.
Warning: It is recommended that you use the Firebase Client SDKs to perform user authentication. Once signed
in via a client SDK, you should pass the logged-in user’s current ID token to your PHP endpoint and verify the ID
token with each request to your backend.
use Kreait\Firebase\Auth;
// $signInResult = $auth->signIn*()
$signInResult->idToken(); // string|null
$signInResult->firebaseUserId(); // string|null
$signInResult->accessToken(); // string|null
$signInResult->refreshToken(); // string|null
$signInResult->data(); // array
$signInResult->asTokenResponse(); // array
SignInResult::data() returns the full payload of the response returned by the Firebase API,
SignInResult::asTokenResponse() returns the Sign-In result in a format that can be returned to clients:
$tokenResponse = [
'token_type' => 'Bearer',
'access_token' => '...',
'id_token' => '...',
'refresh_token' => '...',
'expires_in' => 3600,
];
Anonymous Sign In
Note: This method will create a new user in the Firebase Auth User Database each time it is invoked
$signInResult = $auth->signInAnonymously();
$signInResult = $auth->signInWithCustomToken($customToken);
$signInResult = $auth->signInWithRefreshToken($refreshToken);
IdP (Identitiy Provider) credentials are credentials provided by authentication providers other than Firebase, for ex-
ample Facebook, Github, Google or Twitter. You can find the currently supported authentication providers in the
constants of https://github.com/kreait/firebase-php/blob/master/src/Firebase/Value/Provider.php
This could be useful if you already have “Sign in with Twitter” implemented in your application, and want to authen-
ticate the same user with Firebase.
Once you have received those credentials, you can use them to sign a user in with them, for example with Twitter:
use Kreait\Firebase\Value\Provider;
This will revoke all sessions for a specified user and disable any new ID tokens for existing sessions from getting
minted. Existing ID tokens may remain active until their natural expiration (one hour). To verify that ID tokens
are revoked, use Auth::verifyIdToken() with the second parameter set to true.
If the check fails, a RevokedIdToken exception will be thrown.
use Kreait\Firebase\Exception\Auth\RevokedIdToken;
$auth->revokeRefreshTokens($uid);
1.7. Authentication 33
Firebase Admin SDK for PHP
Note: Because Firebase ID tokens are stateless JWTs, you can determine a token has been revoked only by requesting
the token’s status from the Firebase Authentication backend. For this reason, performing this check on your server is
an expensive operation, requiring an extra network round trip. You can avoid making this network request by setting
up Firebase Rules that check for revocation rather than using the Admin SDK to make the check.
For more information, please visit Google: Detect ID token revocation in Database Rules
The Firebase Admin SDK for PHP provides an API for managing your Firebase users with elevated privileges. The
admin user management API gives you the ability to programmatically retrieve, create, update, and delete users without
requiring a user’s existing credentials and without worrying about client-side rate limiting.
UserRecord s returned by methods from the Kreait\Firebase\Auth class have the following signature:
{
"uid": "jEazVdPDhqec0tnEOG7vM5wbDyU2",
"email": "[email protected]",
"emailVerified": true,
"displayName": null,
"photoUrl": null,
"phoneNumber": null,
"disabled": false,
"metadata": {
"createdAt": "2018-02-14T15:41:32+00:00",
"lastLoginAt": "2018-02-14T15:41:32+00:00",
"passwordUpdatedAt": "2018-02-14T15:42:19+00:00"
},
"providerData": [
{
"uid": "[email protected]",
"displayName": null,
"email": "[email protected]",
"photoUrl": null,
"providerId": "password",
"phoneNumber": null
}
],
"passwordHash": "UkVEQUNURUQ=",
"customClaims": null,
"tokensValidAfterTime": "2018-02-14T15:41:32+00:00"
}
To enhance performance and prevent memory issues when retrieving a huge amount of users, this methods returns a
Generator.
$user = $auth->getUser('some-uid');
$user = $auth->getUserByEmail('[email protected]');
$user = $auth->getUserByPhoneNumber('+49-123-456789');
The Admin SDK provides a method that allows you to create a new Firebase Authentication user. This method accepts
an object containing the profile information to include in the newly created user account:
$userProperties = [
'email' => '[email protected]',
'emailVerified' => false,
'phoneNumber' => '+15555550100',
'password' => 'secretPassword',
'displayName' => 'John Doe',
'photoUrl' => 'http://www.example.com/12345678/photo.png',
'disabled' => false,
];
$createdUser = $auth->createUser($userProperties);
$request = \Kreait\Auth\Request\CreateUser::new()
->withUnverifiedEmail('[email protected]')
->withPhoneNumber('+15555550100')
->withClearTextPassword('secretPassword')
->withDisplayName('John Doe')
->withPhotoUrl('http://www.example.com/12345678/photo.png');
$createdUser = $auth->createUser($request);
By default, Firebase Authentication will generate a random uid for the new user. If you instead want to specify your
own uid for the new user, you can include in the properties passed to the user creation method:
$properties = [
'uid' => 'some-uid',
// other properties
];
$request = \Kreait\Auth\Request\CreateUser::new()
->withUid('some-uid')
// with other properties
;
Note: All of the above properties are optional. If a certain property is not specified, the value for that property will
be empty unless a default is mentioned in the above table.
Note: If you provide none of the properties, an anonymous user will be created.
Updating a user works exactly as creating a new user, except that the uid property is required:
$uid = 'some-uid';
$properties = [
'displayName' => 'New display name'
];
$request = \Kreait\Auth\Request\UpdateUser::new()
->withDisplayName('New display name');
In addition to the properties of a create request, the following properties can be provided:
$uid = 'some-uid';
$uid = 'some-uid';
$uid = 'some-uid';
$updatedUser = $auth->disableUser($uid);
$uid = 'some-uid';
$updatedUser = $auth->enableUser($uid);
Note: Learn more about custom attributes/claims in the official documentation: Control Access with Custom Claims
and Security Rules
// The new custom claims will propagate to the user's ID token the
// next time a new one is issued.
$auth->setCustomUserClaims($uid, ['admin' => true, 'key1' => 'value1']);
The custom claims object should not contain any OIDC reserved key names or Firebase reserved names. Custom
claims payload must not exceed 1000 bytes.
$uid = 'some-uid';
$auth->deleteUser($uid);
The Firebase Admin SDK provides the ability to send users emails containing links they can use for password resets,
email address verification, and email-based sign-in. These emails are sent by Google and have limited customizability.
If you want to instead use your own email templates and your own email delivery service, you can use the Firebase
Admin SDK to programmatically generate the action links for the above flows, which you can include in emails to
your users.
Action Code Settings allow you to pass additional state via a continue URL which is accessible after the user clicks
the email link. This also provides the user the ability to go back to the app after the action is completed. In addition,
you can specify whether to handle the email action link directly from a mobile application when it is installed or from
a browser.
For links that are meant to be opened via a mobile app, you’ll need to enable Firebase Dynamic Links and perform
some tasks to detect these links from your mobile app. Refer to the instructions on how to configure Firebase Dynamic
Links for email actions.
androidPackageName string|null
Sets the Android package name.
This will try to open the link in an
android app
if it is installed.
androidInstallApp bool|null
Whether to install the Android app
if the device supports it and the app
is not
already installed. If this field is
provided without a
androidPackageName,
an error is thrown explaining that
the packageName must be provided
in
conjunction with this field.
androidMinimumVersion string|null
If specified, and an older version of
the app is installed,
the user is taken to the Play Store to
upgrade the app.
The Android app needs to be
registered in the Console.
iOSBundleId string|null
Sets the iOS bundle ID. This will
try to open the link in an iOS app if
it is
installed. The iOS app needs to be
registered in the Console.
1.8. User management 39
Firebase Admin SDK for PHP
Example:
$actionCodeSettings = [
'continueUrl' => 'https://www.example.com/checkout?cartId=1234',
'handleCodeInApp' => true,
'dynamicLinkDomain' => 'coolapp.page.link',
'androidPackageName' => 'com.example.android',
'androidMinimumVersion' => '12',
'androidInstallApp' => true,
'iOSBundleId' => 'com.example.ios',
];
Email verification
To generate an email verification link, provide the existing user’s unverified email and optional Action Code Settings.
The email used must belong to an existing user. Depending on the method you use, an email will be sent to the user,
or you will get an email action link that you can use in a custom email.
$link = $auth->getEmailVerificationLink($email);
$link = $auth->getEmailVerificationLink($email, $actionCodeSettings);
$auth->sendEmailVerificationLink($email);
$auth->sendEmailVerificationLink($email, $actionCodeSettings);
$auth->sendEmailVerificationLink($email, null, $locale);
$auth->sendEmailVerificationLink($email, $actionCodeSettings, $locale);
Password reset
To generate a password reset link, provide the existing user’s email and optional Action Code Settings. The email used
must belong to an existing user. Depending on the method you use, an email will be sent to the user, or you will get
an email action link that you can use in a custom email.
$link = $auth->getPasswordResetLink($email);
$link = $auth->getPasswordResetLink($email, $actionCodeSettings);
$auth->sendPasswordResetLink($email);
$auth->sendPasswordResetLink($email, $actionCodeSettings);
$auth->sendPasswordResetLink($email, null, $locale);
$auth->sendPasswordResetLink($email, $actionCodeSettings, $locale);
Note: Before you can authenticate users with email link sign-in, you will need to enable email link sign-in for your
Firebase project.
Note: Unlike password reset and email verification, the email used does not necessarily need to belong to an existing
user, as this operation can be used to sign up new users into your app via email link.
Note: The ActionCodeSettings object is required in this case to provide information on where to return the user after
the link is clicked for sign-in completion.
To generate a sign-in link, provide the user’s email and Action Code Settings. Depending on the method you use, an
email will be sent to the user, or you will get an email action link that you can use in a custom email.
$auth->sendSignInWithEmailLink($email, $actionCodeSettings);
$auth->sendSignInWithEmailLink($email, $actionCodeSettings, $locale);
Note: Out of the box, Firebase handles the confirmation of password reset requests. You can use your own server to
handle account management emails by following the instructions on Customize account management emails and SMS
messages
$oobCode = '...'; // Extract the OOB code from the request url (not scope of the SDK
˓→(yet :)))
$newPassword = '...';
$invalidatePreviousSessions = true; // default, will revoke current user refresh
˓→tokens
try {
$auth->confirmPasswordReset($oobCode, $newPassword, $invalidatePreviousSessions);
} catch (\Kreait\Firebase\Exception\Auth\ExpiredOobCode $e) {
// Handle the case of an expired reset code
} catch (\Kreait\Firebase\Exception\Auth\InvalidOobCode $e) {
// Handle the case of an invalid reset code
} catch (\Kreait\Firebase\Exception\AuthException $e) {
// Another error has occurred
}
You can create short Dynamic Links with the Firebase Admin SDK for PHP. Dynamic Links can be
• a long Dynamic Link
• an array containing Dynamic Link parameters
• an action created with builder methods
and will return a URL like https://example.page.link/wXYZ.
Note: Short Dynamic Links created via the REST API or this SDK do not show up in the Firebase console. Such
Dynamic Links are intended for user-to-user sharing. For marketing use cases, continue to create your links directly
through the Dynamic Links page of the Firebase console.
Before you start, please read about Dynamic Links in the official documentation:
class MyService
{
public function __construct(DynamicLinks $dynamicLinks)
{
$this->dynamicLinks = $dynamicLinks;
}
}
You can create a Dynamic Link by using one of the methods below. Each method will return an instance of
Kreait\Firebase\DynamicLink.
use use Kreait\Firebase\DynamicLink\CreateDynamicLink\FailedToCreateDynamicLink;
$url = 'https://www.example.com/some/path';
$link = $dynamicLinks->createShortLink($url);
$link = $dynamicLinks->createDynamicLink($url, CreateDynamicLink::WITH_SHORT_
˓→SUFFIX);
If createDynamicLink() is called without a second parameter, the Dynamic Link is created with an unguessable
suffix.
Unguessable suffixes have a length of 17 characters, short suffixes a length of 4 characters. You can learn more about
the length of Dynamic Links in the official documentation.
The returned object will be an instance of Kreait\Firebase\DynamicLink with the following accessors:
$link->uri(); // Psr\Http\Message\UriInterface
$link->previewUri(); // Psr\Http\Message\UriInterface
$link->domain(); // string
$link->suffix(); // string
$link->hasWarnings(); // bool
$link->warnings(); // array
If you have a manually constructed link, you can convert it to a short link:
use Kreait\Firebase\DynamicLink\ShortenLongDynamicLink\FailedToShortenLongDynamicLink;
$longLink = 'https://example.page.link?link=https://domain.tld/some/path';
try {
$link = $dynamicLinks->shortenLongDynamicLink($longLink);
$link = $dynamicLinks->shortenLongDynamicLink($longLink,
˓→ShortenLongDynamicLink::WITH_UNGUESSABLE_SUFFIX);
$link = $dynamicLinks->shortenLongDynamicLink($longLink,
˓→ShortenLongDynamicLink::WITH_SHORT_SUFFIX);
If shortenLongDynamicLink() is called without a second parameter, the Dynamic Link is created with an
unguessable suffix.
You can use this REST API to get analytics data for each of your short Dynamic Links, whether created in the console
or programmatically.
Note: These statistics might not include events that have been logged within the last 36 hours.
use
˓→Kreait\Firebase\DynamicLink\GetStatisticsForDynamicLink\FailedToGetStatisticsForDynamicLink;
˓→
try {
$stats = $dynamicLinks->getStatistics('https://example.page.link/wXYZ');
$stats = $dynamicLinks->getStatistics('https://example.page.link/wXYZ', 14); //
˓→duration in days
If getStatistics() is called without a second parameter, stats will include the statistics of the past 7 days.
The returned object will be an instance of Kreait\Firebase\DynamicLink\DynamicLinkStatistics,
which currently only includes event statistics. You can access the raw returned data with $stats->rawData().
Event Statistics
Firebase Dynamic Links tracks the number of times each of your short Dynamic Links have been clicked, as well as
the number of times a click resulted in a redirect, app install, app first-open, or app re-open, including the platform on
which that event occurred.
Each of the following methods returns a (filtered) instance of Kreait\Firebase\DynamicLink\EventStatistics
which supports any combination of filters and is countable with count() or ->count() as shown below:
$eventStats = $stats->eventStatistics();
$allClicks = $eventStats->clicks();
$allRedirects = $eventStats->redirects();
$allAppInstalls = $eventStats->appInstalls();
$allAppFirstOpens = $eventStats->appFirstOpens();
$allAppReOpens = $eventStats->appReOpens();
$allAndroidEvents = $eventStats->onAndroid();
$allDesktopEvents = $eventStats->onDesktop();
$allIOSEvents = $eventStats->onIOS();
$clicksOnDesktop = $eventStats->clicks()->onDesktop();
$appInstallsOnAndroid = $eventStats->onAndroid()->appInstalls();
$appReOpensOnIOS = $eventStats->appReOpens()->onIOS();
$totalAmountOfClicks = count($eventStats->clicks());
$totalAmountOfAppFirstOpensOnAndroid = $eventStats->appFirstOpens()->onAndroid()->
˓→count();
});
Using actions
$action = CreateDynamicLink::forUrl($url)
->withDynamicLinkDomain('https://example.page.link')
->withUnguessableSuffix() // default
// or
->withShortSuffix()
->withAnalyticsInfo(
AnalyticsInfo::new()
->withGooglePlayAnalyticsInfo(
GooglePlayAnalytics::new()
->withGclid('gclid')
->withUtmCampaign('utmCampaign')
->withUtmContent('utmContent')
->withUtmMedium('utmMedium')
->withUtmSource('utmSource')
->withUtmTerm('utmTerm')
)
->withItunesConnectAnalytics(
ITunesConnectAnalytics::new()
->withAffiliateToken('affiliateToken')
->withCampaignToken('campaignToken')
->withMediaType('8')
->withProviderToken('providerToken')
)
)
->withNavigationInfo(
NavigationInfo::new()
->withoutForcedRedirect() // default
// or
->withForcedRedirect()
)
->withIOSInfo(
IOSInfo::new()
->withAppStoreId('appStoreId')
->withBundleId('bundleId')
->withCustomScheme('customScheme')
->withFallbackLink('https://fallback.domain.tld')
->withIPadBundleId('iPadBundleId')
->withIPadFallbackLink('https://ipad-fallback.domain.tld')
)
->withAndroidInfo(
AndroidInfo::new()
->withFallbackLink('https://fallback.domain.tld')
->withPackageName('packageName')
->withMinPackageVersionCode('minPackageVersionCode')
)
->withSocialMetaTagInfo(
SocialMetaTagInfo::new()
->withDescription('Social Meta Tag description')
->withTitle('Social Meta Tag title')
->withImageLink('https://domain.tld/image.jpg')
(continues on next page)
$link = $dynamicLinks->createDynamicLink($action);
If you prefer using a parameter array to configure a Dynamic Link, or if this SDK doesn’t yet have support for a given
new option, you can pass an array to the createDynamicLink() method. As the parameters will not be processed
or validated by the SDK, you have to make sure that the parameter structure matches the one described in the API
Reference Documentation
$parameters = [
'dynamicLinkInfo' => [
'domainUriPrefix' => 'https://example.page.link',
'link' => 'https://domain.tld/some/path',
],
'suffix' => ['option' => 'SHORT'],
];
try {
$link = $dynamicLinks->createDynamicLink($parameters);
} catch (FailedToCreateDynamicLink $e) {
echo $e->getMessage(); exit;
}
Change the behavior and appearance of your app without publishing an app update.
Firebase Remote Config is a cloud service that lets you change the behavior and appearance of your app without
requiring users to download an app update. When using Remote Config, you create in-app default values that control
the behavior and appearance of your app.
Before you start, please read about Firebase Remote Config in the official documentation:
• Firebase Remote Config
For Firebase projects created before the March 7, 2018 release of the Remote Config REST API, you must enable the
API in the Google APIs console.
1. Open the Firebase Remote Config API page in the Google APIs console.
2. When prompted, select your Firebase project. (Every Firebase project has a corresponding project in the Google
APIs console.)
3. Click Enable on the Firebase Remote Config API page.
$remoteConfig = $factory->createRemoteConfig();
use Kreait\Firebase\RemoteConfig;
class MyService
{
public function __construct(Database $remoteConfig)
{
$this->remoteConfig = $remoteConfig;
}
}
$remoteConfig = app('firebase.remote_config');
// Added in 4.29.0
$version = $template->version(); // Returns a Kreait\Firebase\RemoteConfig\Version
use Kreait\Firebase\RemoteConfig;
$template = RemoteConfig\Template::new();
use Kreait\Firebase\RemoteConfig;
$germanLanguageCondition = RemoteConfig\Condition::named('lang_german')
->withExpression("device.language in ['de', 'de_AT', 'de_CH']")
->withTagColor(TagColor::ORANGE); // The TagColor is optional
$template = $template->withCondition($germanLanguageCondition);
use Kreait\Firebase\RemoteConfig;
$welcomeMessageParameter = Parameter::named('welcome_message')
->withDefaultValue('Welcome!')
->withDescription('This is a welcome message') // optional
;
use Kreait\Firebase\RemoteConfig;
$germanLanguageCondition = RemoteConfig\Condition::named('lang_german')
->withExpression("device.language in ['de', 'de_AT', 'de_CH']");
$germanWelcomeMessage = RemoteConfig\ConditionalValue::basedOn(
˓→$germanLanguageCondition, 'Willkommen!');
$welcomeMessageParameter = Parameter::named('welcome_message')
->withDefaultValue('Welcome!')
->withConditionalValue($germanWelcomeMessage);
$template = $template
->withCondition($germanLanguageCondition)
->withParameter($welcomeMessageParameter);
Note: When you use a conditional value, make sure to add the corresponding condition to the template first.
1.10.8 Validation
Usually, the SDK will protect you from creating an invalid Remote Config template in the first place. If you want to
be sure, you can validate the template with a call to the Firebase API:
use Kreait\Firebase\Exception\RemoteConfig\ValidationFailed;
try {
$remoteConfig->validate($template);
} catch (ValidationFailed $e) {
echo $e->getMessage();
}
use Kreait\Firebase\Exception\RemoteConfigException
try {
(continues on next page)
Since August 23, 2018, Firebase provides a change history for your published Remote configs.
The following properties are available from a Kreait\Firebase\RemoteConfig\Version object:
$version->versionNumber();
$version->user(); // The user/service account the performed the change
$version->description();
$version->updatedAt();
$version->updateOrigin();
$version->updateType();
$version->rollBackSource();
List versions
To enhance performance and prevent memory issues when retrieving a huge amount of versions, this methods returns
a Generator.
// or
Filtering
use Kreait\Firebase\RemoteConfig\FindVersions;
$query = FindVersions::all()
// Versions created/updated after August 1st, 2019 at midnight
->startingAt(new DateTime('2019-08-01 00:00:00'))
// Versions created/updated before August 7th, 2019 at the end of the day
->endingAt(new DateTime('2019-08-06 23:59:59'))
// Versions with version numbers smaller than 3464
->upToVersion(VersionNumber::fromValue(3463))
// Setting a page size can results in faster first results,
// but results in more request
->withPageSize(5)
// Stop querying after the first 10 results
(continues on next page)
$query = [
'startingAt' => '2019-08-01',
'endingAt' => '2019-08-07',
'upToVersion' => 9999,
'pageSize' => 5,
'limit' => 10,
];
$version = $remoteConfig->getVersion($versionNumber);
Rollback to a version
$template = $remoteConfig->rollbackToVersion($versionNumber);
kreait provides and maintains the following framework integrations for the Firebase Admin SDK for PHP:
1.11.1 Laravel
kreait/laravel-firebase
1.11.2 Symfony
kreait/firebase-bundle
1.11.3 CodeIgniter
tatter/firebase
1.12 Tutorials
You can find an example project implementing the Firebase Admin SDK for PHP at https://github.com/jeromegamez/
firebase-php-examples .
In addition, the SDK has been featured in the following tutorials.
Warning: Articles and videos prefixed with [4.x] are targeted at Release 4.x of the SDK. Processes and method
names can be different in the current release.
Please look at the current documentation and adapt your code accordingly.
1.12.1 Articles
• [4.x] How to integrate Laravel with Google Firebase by Javier Núñez (English, April 2019)
• [4.x] Integrate Firebase With PHP and Optimize Your Real Time Communication by Shahroze Nawaz (English,
November 2018)
• [4.x] Connect Laravel with Firebase Real Time Database by Pardeep Kumar (English, March 2018)
1.12.2 Videos
• [4.x] Firebase for Web | PHP Tutorial by Umar Hameed (Hindi/Urdu, January 2019)
• [4.x] Firebase and PHP by Arthur Mann (English, August 2018)
Note: Do you know another tutorial that is not featured in this list? Then please consider adding it by creating a Pull
Request in the GitHub Repository of this project.
1.13 Troubleshooting
Note: This SDK works with immutable objects until noted otherwise. You can recognize these objects when they
have a ‘with*‘‘method. In that case, please keep in mind that in order to get hold of the changes you made, you will
have to use the result of that method, e.g. $changedObject = $object->withChangedProperty();.
you have most likely followed a tutorial that is targeted at Version 4.x of this release and have code that looks like this:
1.12. Tutorials 51
Firebase Admin SDK for PHP
$serviceAccount = ServiceAccount::fromJsonFile(__DIR__.'/google-service-account.json
˓→');
$database = $firebase->getDatabase();
$database = $factory->createDatabase();
the environment you are running the script in does not use PHP 7.x. You can check this by adding the line
echo phpversion(); exit;
You are not using the latest release of the SDK, please update your composer dependencies.
If you receive a cURL error XX: ..., make sure that you have a current CA Root Certificates bundle on your
system and that PHP uses it.
To see where PHP looks for the CA bundle, check the output of the following command:
var_dump(openssl_get_cert_locations());
Now check if the file given in the default_cert_file field actually exists. Create a backup of the file, download
the current CA bundle from https://curl.haxx.se/ca/cacert.pem and put it where default_cert_file points to.
If the problem still occurs, another possible solution is to configure the curl.cainfo setting in your php.ini:
[curl]
curl.cainfo = /absolute/path/to/cacert.pem
When ID Token verification fails because of an IssuedInTheFuture exception, this is an indication that the
system time in your environment is not set correctly.
If you chose to ignore the issue, you can catch the exception and return the ID token nonetheless:
use Firebase\Auth\Token\Exception\InvalidToken;
use Firebase\Auth\Token\Exception\IssuedInTheFuture;
$auth = $factory->createAuth();
try {
return $auth->verifyIdToken($idTokenString);
} catch (IssuedInTheFuture $e) {
return $e->getToken();
} catch (InvalidIdToken $e) {
echo $e->getMessage();
exit;
}
Under the hood, a Firebase project is actually a Google Cloud project with pre-defined and pre-allocated permissions
and resources.
When Google adds features to its product line, it is possible that you have to manually configure your Firebase/Google
Cloud Project to take advantage of those new features.
When a request to the Firebase APIs fails, please make sure that the according Google Cloud API is enabled for your
project:
• Firebase Services: https://console.cloud.google.com/apis/library/firebase.googleapis.com
• Cloud Messaging (FCM): https://console.cloud.google.com/apis/library/fcm.googleapis.com
1.13. Troubleshooting 53
Firebase Admin SDK for PHP
This is an issue seen in XAMPP/WAMP environments and seems related to the cURL version shipped with the current
PHP installation. Please ensure that cURL is installed with at least version 7.67 (preferably newer, version 7.70 is
known to work).
You can check the currently installed cURL version by adding the following line somewhere in your code:
To install a newer version of cURL, download the latest release from https://curl.haxx.se/ . From the unpacked archive
in the bin folder, use the file ending with libcurl*.dll to overwrite the existing libcurl*.dll in the ext
folder of your PHP installation and restart the environment.
If this issue occurs in other environments (e.g. Linux or MacOS), please ensure that you have the latest (minor)
versions of PHP and cURL installed. If the problem persists, please open an issue in the issue tracker.
If you need to access the Firebase/Google APIs through a proxy, you can configure the SDK to use one via Guzzle’s
proxy configuration:
$factory = $factory->withHttpProxy('tcp://<host>:<port>');
1.13.10 Debugging
In order to debug HTTP requests to the Firebase/Google APIs, you can enable the factory’s debug mode and provide
an instance of Psr\Log\LoggerInterface. HTTP requests and responses will then be pushed to this logger
with their full headers and bodies.
$factory = $factory->withEnabledDebug($logger);