Closed nicolasvahidzein closed 2 years ago
Hey @nicolasvahidzein! 👋
The Firebase::project()
route is the one I would use to access multiple projects, so you're almost there!
// Will return the Auth Component of the client mobile app
// and is an instance of Kreait\Firebase\Contract\Auth
$auth = Firebase::project('client_mobile_app')->auth();
// Will return the Messaging Component of the admin mobile app
// and is an instance of Kreait\Firebase\Contract\Messaging
$messaging = Firebase::project('admin_mobile_app')->messaging();
The app(...)
notation will only work in applications that use one single project.
You can find available methods to get the components you might need in https://github.com/kreait/laravel-firebase/blob/main/src/FirebaseProject.php.
If you want to use multiple projects inside of one Application Service in your project, you could do something like this:
use Kreait\Laravel\Firebase\FirebaseProject;
use Kreait\Laravel\Firebase\FirebaseProjectManager;
class MyService
{
private FirebaseProject $clientMobileApp;
private FirebaseProject $adminMobileApp;
public function __construct(FirebaseProjectManager $manager)
{
$this->clientMobileApp = $manager->project('client_mobile_app');
$this->adminMobileApp = $manager->project('admin_mobile_app');
}
public function doSomething()
{
// ...
}
}
I hope this helps!
You are the best as usual. Thanks a million. I'll revert back as soon as i have the new project up and running.
Are these still valid @jeromegamez?
I noticed the namespace changed on the main functions.
use Kreait\Firebase\Messaging\RawMessageFromArray; use Kreait\Firebase\Exception\Messaging\InvalidArgument; use Kreait\Firebase\Exception\Messaging\NotFound; use Kreait\Firebase\Exception\Messaging\InvalidMessage;
Yes, they should still be valid, but you can always check on the classes/exceptions themselves, either in the vendor/kreait/firebase-php
directory, or in the web UI at https://github.com/kreait/firebase-php 😅
If you want to see what changed between the 5.x and 6.x releases, the Changelog can help: https://github.com/kreait/firebase-php/blob/6.x/CHANGELOG.md#600---2022-01-07
Wonderful. Thanks Jerome!
Quick question Jerome, i am getting this error in VSCODE:
syntax error, unexpected 'FirebaseProject' (T_STRING), expecting function (T_FUNCTION) or const (T_CONST)
Is it just my IDE or did I forget something?
It's either your IDE or the underlying PHP version is too old. The package and the SDK need at least PHP 7.4
I'm currently on the phone so I can't be sure that I'm 100% accurate, but you can configure the used PHP version in PHPStorm in the Preferences. It should be something like "Local interpreters" or "Remote interpreters" or "Language Level". There you should be able to change the PHP version for the current project 🤞🏻
Wonderful, thank you for your guidance Jerome. I will look into it and revert back. Good day to you.
sorry again for the bother Jerome, I don't get where i should be passing the manager from nor where to get it:
FirebaseProjectManager $manager
from here:
public function __construct(FirebaseProjectManager $manager)
I have been looking inside the package for mentions of manager and i found this:
$manager = $this->app->make(FirebaseProjectManager::class);
BUT i do not know where i place this nor where i call it from. I get the following error when i try to pass that line of code from the parent function to pass this argument:
local.ERROR: Undefined property: App\Methods\Notifications\SendNotification::$app {"userId":17,"exception":"[object] (ErrorException(code: 0): Undefined property: App\\Methods\\Notifications\\SendNotification::$app at /var/www/html/zeintek/merlin/back_end2/app/Methods/Notifications/SendNotification.php:368)
Nicolas, I hope you know that what we're doing here is not "I found a bug" but "individual support for GitHub Sponsors in Slack" stuff 😅, (please read this in a friendly tone).
I'll update the Readme with a usage example once I can reach my computer so that others can benefit from it in a more accessible place than here in this thread 🤞🏻
I just got the notification about your donation, thank you very much! 🥰 Then let's continue 🫣😂
I know I am a pain right now, my apologies Jerome. I know you mean it nicely. It was actually a good reminder. Check your sponsor page!!!
PS: I THINK I got it to work but the way i did it is not as elegant as yours:
$manager = $this->app->make(FirebaseProjectManager::class);
$clientMobileApp = $manager->project('client_mobile_app');
$adminMobileApp = $manager->project('admin_mobile_app');
That's exactly the way to go and will work! But there's an even more elegant way to do it, I'm sure you'll like it! Give me an hour or two, I need my computer to write it up 🙏🏻
ok perfect. Thank you Jerome.
BTW: same error:
$app {"exception":"[object] (ErrorException(code: 0): Undefined property: App\Jobs\PushMessaging\SendPushNotification::$app at /var/www/html/zeintek/merlin/back_end2/app/Jobs/PushMessaging/
As far as I know, and if I guess this right from the error, you don't have the app available in a job. You need to inject the FirebaseProjectManager into the job by adding it as a parameter to the handle() method.
Ok let me try it
In your example a while back you were injecting it in the construct method i think. I will see if it works in the handle method.
For services, yes, but jobs work differently
https://laravel.com/docs/9.x/queues#handle-method-dependency-injection
I'm lost with this. I don't mind passing it in the construct method i just do not know how to pass it, or I am doing something wrong.
I'll wait until you are in front of a computer for a complete example since i'm not an expert and this dependency injection is throwing me for a loop.
BTW, i'm already passing 7 arguments and so when i had the dependency injection as the 8th parameter i get an error. Just wanted to clarify.
Alright, here's how I set up an example project
$ composer create-project laravel/laravel laravel9-with-firebase
$ cd laravel9-with-firebase
$ php artisan vendor:publish --provider="Kreait\Laravel\Firebase\ServiceProvider" --tag=config
$ php artisan make:controller FirebaseController
$ php artisan make:job SendFirebasePushNotification
# .env
APP_NAME=Laravel
APP_ENV=local
# all other variables unchanged and added at the bottom:
FIREBASE_PROJECT_A_CREDENTIALS=/path/to/project_a_credentials.json
FIREBASE_PROJECT_A_DB_URL=https://project-a.firebaseio.com
FIREBASE_PROJECT_B_CREDENTIALS=/path/to/project_b_credentials.json
FIREBASE_PROJECT_B_DB_URL=https://project-b.firebaseio.com
<?php
# config/firebase.php
return [
/*
* ------------------------------------------------------------------------
* Default Firebase project
* ------------------------------------------------------------------------
*/
'default' => env('FIREBASE_PROJECT', 'project_a'),
/*
* ------------------------------------------------------------------------
* Firebase project configurations
* ------------------------------------------------------------------------
*/
'projects' => [
'project_a' => [
'credentials' => [
'file' => env('FIREBASE_PROJECT_A_CREDENTIALS'),
],
'database' => [
'url' => env('FIREBASE_PROJECT_A_DB_URL'),
],
],
'project_b' => [
'credentials' => [
'file' => env('FIREBASE_PROJECT_B_CREDENTIALS'),
],
'database' => [
'url' => env('FIREBASE_PROJECT_B_DB_URL'),
],
],
],
];
<?php
# routes/web.php
use App\Http\Controllers\FirebaseUserController;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
Route::get('firebase/users/{projectId}', [FirebaseUserController::class, 'index']);
<?php
# app/Http/Controllers/FirebaseUserController
namespace App\Http\Controllers;
use Kreait\Laravel\Firebase\FirebaseProjectManager;
class FirebaseUserController extends Controller
{
public function __construct(private FirebaseProjectManager $firebase)
{
}
public function index(string $projectId)
{
return $this->firebase
->project($projectId)
->auth()
->queryUsers([
'limit' => 2
]);
}
}
<?php
# app/Jobs/SendFirebasePushNotification
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Kreait\Firebase\Messaging\CloudMessage;
use Kreait\Firebase\Messaging\Notification;
use Kreait\Laravel\Firebase\FirebaseProjectManager;
class SendFirebasePushNotification implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(
public string $projectId,
public string $registrationToken
) {}
public function handle(FirebaseProjectManager $projectManager): void
{
$message = [
'token' => $this->registrationToken,
'notification' => [
'title' => 'Notification title',
'body' => 'Notification body'
],
];
$result = $projectManager
->project($this->projectId)
->messaging()
->send($message);
Log::info('Push notification sent', [
'message' => $message,
'result' => $result,
]);
}
}
Assuming that the application is available at http://laravel9-with-firebase.test/
, you can now call
and will get users from the respective project
You can test the Job with laravel tinker
(you need a real, working registration to replay this without errors):
$ php artisan tinker
Psy Shell v0.11.8 (PHP 8.1.9 — cli) by Justin Hileman
>>> App\Jobs\SendFirebasePushNotification::dispatchSync('project_a', 'registration_token');
=> 0
This will result in a new entry in storage/logs/laravel.log
:
[2022-09-03 17:54:17] local.INFO: Push notification sent {"message":{"token":"registration_token","notification":{"title":"Notification title","body":"Notification body"}},"result":{"name":"projects/beste-firebase/messages/db11e06b-a585-4f3f-b702-b80044b1b185"}}
Depending on how you do things in your project, you could also create the Message beforehand and pass that to the job:
<?php
# app/Jobs/SendFirebaseMessage.php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Kreait\Firebase\Messaging\Message;
use Kreait\Laravel\Firebase\FirebaseProjectManager;
use Throwable;
class SendFirebaseMessage implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(
public string $project,
public Message $message
)
{
}
public function handle(FirebaseProjectManager $projectManager)
{
try {
$projectManager->project($this->project)
->messaging()
->send($this->message);
Log::info('Message sent');
} catch (Throwable $e) {
Log::warning('The message could not be sent', [
'exception' => $e
]);
}
}
}
I hope this helps! I think I will use the opportunity to create an example application similar to https://github.com/jeromegamez/firebase-php-examples but for Laravel, now that I've set it up anyway :D
I'm closing this because the OP was long done. You can continue to add comments, but don't need to reopen the issue, I get notified anyway 😊
Ok I thought i had to reopen it. Sorry. Thanks for the code. I'll take the time to read it in detail and revert back. Thanks so much.
All is well now thanks @jeromegamez
The issue was passing it in the handle and not the constructor. Thank you so much.
Glad it worked out!
Hello @jeromegamez! How are you?
I had to bite the bullet and upgrade my laravel installation to the latest one. I am on v 9.19 now and all should be better now.
I just wanted to clarify the following:
in the config file for laravel i added to entries under project like so:
So now according to the instructions i should use these two variables to call each projecet: admin_mobile_app/client_mobile_app
except i'm confused on how to do it exactly, the readme stops at at how to use it for auth.
i used to have this with the provider you built for me (thanks a million btw):
but now, how do I do it? Is this correct?
or this route? (i must remove auth i am guessing):