kreait / laravel-firebase

A Laravel package for the Firebase PHP Admin SDK
https://github.com/kreait/firebase-php
MIT License
1.1k stars 174 forks source link

Multiple authentication issues #141

Closed nicolasvahidzein closed 2 years ago

nicolasvahidzein commented 2 years ago

Hello,

Thank you first of all for this wonderful package that is a lifesaver!

I wanted to know how i can configure my laravel instance to send to 2 different apps each with their own google services json file.

I'm guessing it needs to be configured in the firebase.php settings file and i need to add a new entry in the env file but is there a more complete documentation i can look up or a tutorial?

Thanks.

jeromegamez commented 2 years ago

It is possible if you have a look at https://github.com/kreait/laravel-firebase#multiple-projects and then at https://github.com/kreait/laravel-firebase/blob/main/config/firebase.php

Here you can make a copy of the app array and configure it with the settings of your second app (you can use other keys and don't have to stick with app, instead you could use project_1 and project_2, to give a bad example 😅)

If you want to provide both with paths to different json files, you can either hardcode them or introduce new environment variables.

I'm currently not at my computer so I can't provide no full examples right now (writing code blocks on a phone is hard), but I hope I could shed some light 🤞

nicolasvahidzein commented 2 years ago

Thank you so much @jeromegamez.

I will look at that tonight and revert back tomorrow. I am about to launch and worried about this so i can totally pay for an hour of your time for some hand holding tomorrow at any time of your choosing :).

nicolasvahidzein commented 2 years ago

I am using a totally different version i see. Mine just has the credentials array. I'm on "kreait/laravel-firebase": "1.3",

jeromegamez commented 2 years ago

That's a really old version which keeps you at a 4.x release of the SDK which is also really old 😅. I definitely would recommend trying to upgrade those dependencies - depending how closely you stayed with the intended usage and what components you're using, upgrading shouldn't be too much of a hassle - which, I know, is easier said than done 😅, but I do think it's worth it.

About the "hand-holding" session - I'm afraid my time doesn't allow this at the moment, but a GitHub sponsorship starting at a certain tier gives you access to a sponsors-only Slack Channel, in which I can give support, and although it is asynchronous, I usually answer quite promptly during CEST working hours up until late evenings 😅.

Either way I'll try if I can jot down a way how you can set up multiple projects with the 1.x package/4.x SDK in the next hours 🤞 (no promises though 😬)

nicolasvahidzein commented 2 years ago

Brilliant Idea, i will do just that. Speak soon.

nicolasvahidzein commented 2 years ago

I'm curious, I am on PHP 7.3, is there a way to modify the package to run on 7.3 instead of 7.4? That would be a lifesaver. Upgrading anything on my system before i launch v1 would be suicide but this requirement would be easy because on my prod server i can switch out for at least 7.4. Let me know thanks. PS i am officially a sponsor. Thank you for your amazing work Jerome!

jeromegamez commented 2 years ago

Thank you for your donation, it's much appreciated!

I totally get why and that you can't upgrade anything right before launch. Downgrading the new features to PHP 7.3 isn't something I can do, though - for one it would be a massive undertaking, on the other hand I don't support PHP versions that aren't supported anymore themselves 😬.

I'm back at my computer in about half an hour and will work on an example on how you can add multi-project support using the 4.x SDK/1.x Package in your project - it will most likely be creating your own ServiceProvider based on the one provided by the package.

Some questions about your current setup:

nicolasvahidzein commented 2 years ago

Hey Jerome, i meant in the sense that if i went into the package file and changed the minimum version. Would it work you think? Or would that version break the package because it is so different than 7.4?

nicolasvahidzein commented 2 years ago

To answer your questions these are the packages i am using:

"require": {
    "php": "^7.1.3",
    "barryvdh/laravel-cors": "^0.11.3",
    "ankurk91/fcm-notification-channel": "1.0.0",
    "beyondcode/laravel-websockets": "^1.1",
    "fideloper/proxy": "^4.0",
    "giggsey/libphonenumber-for-php": "^8.12",
    "guzzlehttp/guzzle": "^6.5",
    "intervention/image": "^2.5",
    "jenssegers/mongodb": "^3.5",
    "kreait/laravel-firebase": "1.3",
    "krossroad/laravel-union-paginator": "^5.5",
    "laravel/framework": "5.8.*",
    "laravel/passport": "7.3",
    "laravel/tinker": "^1.0",
    "laravolt/avatar": "^2.2",
    "lasserafn/php-initial-avatar-generator": "^4.0",
    "lcobucci/jwt": "3.3.3",
    "predis/predis": "^1.1",
    "prettus/l5-repository": "^2.6",
    "pusher/pusher-php-server": "3.4.1",
    "ramsey/uuid": "^3.8",
    "sayeed/custom-migrate": "^1.0",
    "spatie/laravel-permission": "^2.37",
    "twilio/sdk": "^5.34"
},
"require-dev": {
    "barryvdh/laravel-ide-helper": "^2.6",
    "beyondcode/laravel-dump-server": "^1.0",
    "filp/whoops": "^2.0",
    "fzaninotto/faker": "^1.4",
    "mockery/mockery": "^1.0",
    "nunomaduro/collision": "^3.0",
    "phpunit/phpunit": "^7.5"
},
nicolasvahidzein commented 2 years ago

I am on Laravel 5.8 at the moment.

I am only using the component in a single class because it was a simple and straightforward way for me and i only use the raw component this way:

            $message = new RawMessageFromArray([
                'token' => $deviceToken,
                //'name' => $name,
                //'topic' => $topic,
                //'condition' => $condition,
                'notification' => $notificationPayload,
                'data' => $data,
                'android' => $androidSettings,
                'apns' => $apnsSettings,
                'webpush' => $webpushSettings,
                'fcm_options' => $fcmOptions
            ]);

            $messaging = app('firebase.messaging');

            $sendingInfo = $messaging->send($message);

The full class is a bit longer but just in case you need to see it here it is:

<?php

namespace App\Jobs\PushMessaging;

//system classes
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Kreait\Firebase\Messaging\RawMessageFromArray;
use Kreait\Firebase\Exception\Messaging\InvalidArgument;
use Kreait\Firebase\Exception\Messaging\NotFound;
use Kreait\Firebase\Exception\Messaging\InvalidMessage;
use Ramsey\Uuid\Uuid;
//use Kreait\Firebase\Exception\FirebaseException;
//use Kreait\Firebase\Exception\Messaging\UnknowError;
//use Kreait\Firebase\Messaging;
//use Kreait\Firebase\Messaging\CloudMessage;
//use Kreait\Firebase\Messaging\Notification;
use Illuminate\Support\Facades\Notification;
use Kreait\Firebase\Messaging\MessageTarget;
use App\Notifications\SendFcmNotification;
use Exception;
use Log;

//models
use App\Models\Endpoints;

//Custom methods
use App\Methods\Endpoints\EndpointOperations;

//Issues
//AUDIT_00001-CHECKED

class SendPushNotification implements ShouldQueue {

    private $className = 'App\Jobs\PushMessaging\SendPushNotification.php';
    private $deviceIdentifier;
    private $title;
    private $message;
    private $messageImage;
    private $messagePriority; //unused for now
    private $totalNotifications;
    private $extraPayload;

    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(
        $deviceIdentifier,
        $title,
        $message,
        $messageImage,
        $messagePriority,
        $totalNotifications,
        $extraPayload
    ) {
        $this->deviceIdentifier = $deviceIdentifier;
        $this->title = $title;
        $this->message = $message;
        $this->messageImage = $messageImage;
        $this->messagePriority = $messagePriority;
        $this->totalNotifications = $totalNotifications;
        $this->extraPayload = $extraPayload;
    }

    public function handle() {
        if (config('settings.DebugTraceLevelFunctions') == true) { Log::channel('merlin_debug')->info('handle function in '.$this->className); }//this is a special log function for queue job classes

        //this is a provider agnostic process as it should be. Here though we need to determine which provider or process to use before moving forwarding and doing provider specific tasks

        $pushNotificationsProvider = null;

        //check first for the desired main provider
        switch (config('settings.pushnotificationsPrefered')) {

            case 'pushnotifications_provider_firebase':
                $pushNotificationsProvider = 'pushnotifications_provider_firebase';
                break;

            default:
                $pushNotificationsProvider = config('settings.pushnotificationsdefault');
                break;

        }

        if ($pushNotificationsProvider == 'pushnotifications_provider_firebase') {

            $endpointUID = $this->deviceIdentifier;

            //NEXT_UPDATE EXTRACT THIS TO IT'S OWN CLASS IN THE FUTURE

            //go here for docs for the REST API
            //https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#AndroidNotification

            //FIX_THIS_SOON WE NEED A TRY CATCH LOOP IN THE EVENT THE TOKEN IS DELETED OR THERE IS AN ERROR TO SEE WHAT HAPPENS

            $endpoint = Endpoints::where('UID', '=', $endpointUID)->first();

            Log::channel('merlin_debug')->info('$endpoint:');
            Log::channel('merlin_debug')->info($endpoint);

            $deviceToken = $endpoint->firebase_token;

            Log::channel('merlin_debug')->info('$deviceToken:');
            Log::channel('merlin_debug')->info($deviceToken);

            //FIX_THIS_SOON figure out later how to upgrade to Kreiat version 4 that supports multiple authentication accounts which i cannot do at this time
            if ($endpoint->foreignUID_type == 'client') {
                //we are good to go it is a client endpoint
                Log::channel('merlin_debug')->info('we are good to go it is a client endpoint');

                //keep going

            } else {
                //we are in trouble, it is an admin endpoint (seller, supplier, partner, consultant, employee)
                Log::channel('merlin_debug')->info('we are in trouble, it is an admin endpoint');

                Notification::route('FCM', [$deviceToken/*, 'token_2'*/])
                ->route('FCMTargetType', MessageTarget::TOKEN)
                ->notify(new SendFcmNotification($this->title, $this->message));

                //abort
                Log::channel('merlin_debug')->info('abort');

                return;

            }

            //$name = 'Notification name'; //FIX_THIS_SOON figure this out soon
            $topic = 'Notification topic'; //FIX_THIS_SOON figure this out soon
            $condition = 'Notification condition'; //FIX_THIS_SOON figure this out soon
            $notificationTitle = $this->title;
            $notificationBody = $this->message;
            $notificationIcon = 'https://unsplash.it/200/200'; //FIX_THIS_SOON is this being used?
            $notificationImageUrl = $this->messageImage;
            $notificationPriority = 'high';
            $apnsPayloadBadge = $this->totalNotifications;
            $analyticsLabel = 'zandu-notification'; //FIX_THIS_SOON what do i need to fix here?

            //BYPASS
            $apnsPayloadBadge = 0;//FIX_THIS_SOON until we figure out how to handle changing the notifications on the device when they are clicked on or marked as read or unread in the app, we will no longer send a notification count because we have no way to change it later

            //https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#notification
            $notificationPayload = [
                'title' => $notificationTitle,
                'body' => $notificationBody,
                'image' => $notificationImageUrl,
            ];

            //generate the notification UID
            $pushNotificationUID = Uuid::uuid4();

            //payload needs to be configured from the parent function as an array, don't pass individual elements
            $data = [
                'click_action' => 'FLUTTER_NOTIFICATION_CLICK',
                'priority' => 'high',
                'sound' => 'default',

                //ALL THE OTHER VARIABLES NEEDED HERE WILL BE PASSED IN THE EXTRA PAYLOAD AND APPENDED TO THIS ARRAY

            ];

            Log::channel('merlin_debug')->info('$this->extraPayload:');
            Log::channel('merlin_debug')->info($this->extraPayload);

            Log::channel('merlin_debug')->info('$data before appending any other extra payload variables:');
            Log::channel('merlin_debug')->info($data);

            $extraPayload = $this->extraPayload;

            //LARAVEL-SENSEI-0007
            $extraPayload->each(function ($item, $key) use (&$data) {
                // Do stuff

                //Log::channel('merlin_debug')->info('$key:');
                //Log::channel('merlin_debug')->info($key);
                //Log::channel('merlin_debug')->info('$item:');
                //Log::channel('merlin_debug')->info($item);

                //check to make sure no element in the new property is null, firebase does not like null elements
                if (is_null($key)) {
                    //key or item is INDEED null
                    Log::channel('merlin_debug')->info('key or item is INDEED null');
                    Log::channel('merlin_debug')->info('$key:');
                    Log::channel('merlin_debug')->info($key);
                    Log::channel('merlin_debug')->info('$item:');
                    Log::channel('merlin_debug')->info($item);

                } else {
                    //neither key nor item is null, we can proceed
                    //Log::channel('merlin_debug')->info('neither key nor item is null, we can proceed');

                    $itemData = $item;

                    if (is_null($item)) {

                        $itemData = '';//because firebase does not like null values

                        Log::channel('merlin_debug')->info('key or item is INDEED null');
                        Log::channel('merlin_debug')->info('$key:');
                        Log::channel('merlin_debug')->info($key);
                        Log::channel('merlin_debug')->info('$item:');
                        Log::channel('merlin_debug')->info($item);

                    }

                    //merge the array to the array
                    $data = array_merge($data, array($key => $itemData));

                }

            });

            Log::channel('merlin_debug')->info('$data after integrating the extra payload variables: 333');
            Log::channel('merlin_debug')->info($data);

            $androidTtl = '3600s';

            $androidCollapseKey = '';

            $androidRestrictedPackageName = '';

            $androidNotificationPayload = [
                'title' => $notificationTitle,
                'body' => $notificationBody,
                //'icon' => 'string',
                //'color' => 'string',
                'sound' => 'default',
                //'tag' => 'string',
                'click_action' => 'FLUTTER_NOTIFICATION_CLICK',
                //'body_loc_key' => 'string',
                /* 'body_loc_args' => [
                    'string'
                ], */
                //'title_loc_key' => 'string',
                /* 'title_loc_args' => [
                    'string'
                ], */
                'channel_id' => 'notifications_001',
                //'ticker' => 'string',
                'sticky' => false, //When set to false or unset, the notification is automatically dismissed when the user clicks it in the panel. When set to true, the notification persists even when the user clicks it.
                //'event_time' => 'string',
                'local_only' => true,
                'notification_priority' => 'priority_high', //also priority_max
                'default_sound' => true,
                'default_vibrate_timings' => true,
                'default_light_settings' => true,
                /* 'vibrate_timings' => [
                    'string'
                ], */
                //'visibility' => 'private',
                //'notification_count' => integer,
                /* 'light_settings' => {
                    "color" => {
                        object (Color)
                    },
                    "light_on_duration": string,
                    "light_off_duration": string
                }, */ //i can't get to write the object properly
                //'image' => $notificationImageUrl
            ];

            $androidFcmOptions = [
                'analytics_label' => $analyticsLabel //optional
            ];

            $webPushHeaders = [
                'Urgency' => 'high',
            ];

            $webPushFcmOptions = [
                //'link' => '',
                'analytics_label' => $analyticsLabel //optional
            ];

            $apnsHeaders = [
                'apns-priority' => '10',
                //'mutable-content' => 1,//FIX_THIS_SOON find out if i need this later for displaying images in ios if not remove it
            ];

            $apnsPayload = [
                'aps' => [
                    'alert' => [
                        'title' => $notificationTitle,
                        'body' => $notificationBody,
                    ],
                    'badge' => $apnsPayloadBadge,
                ],
            ];

            $apnsFcmOptions = [
                //'image' => '',
                'analytics_label' => $analyticsLabel //optional
            ];

            //https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#androidconfig
            $androidSettings = [
                'ttl' => $androidTtl,
                'priority' => $notificationPriority,
                //'collapse_key' => $androidCollapseKey,
                //'restricted_package_name' => $androidRestrictedPackageName,
                'notification' => $androidNotificationPayload,
                'data' => $data,
                'fcm_options' => $androidFcmOptions,
            ];

            //https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#apnsconfig
            $apnsSettings = [
                'headers' => $apnsHeaders,
                'payload' => $apnsPayload,
                'fcm_options' => $apnsFcmOptions,
            ];

            //https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#webpushconfig
            $webpushSettings = [
                'headers' => $webPushHeaders,
                'notification' => $androidNotificationPayload,
                'data' => $data,
                'fcm_options' => $webPushFcmOptions,
            ];

            //hide fcm_options if you are leaving it empty
            //https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#fcmoptions
            $fcmOptions = [
                'analytics_label' => $analyticsLabel //optional
            ];

            $message = new RawMessageFromArray([
                'token' => $deviceToken,
                //'name' => $name,
                //'topic' => $topic,
                //'condition' => $condition,
                'notification' => $notificationPayload,
                'data' => $data,
                'android' => $androidSettings,
                'apns' => $apnsSettings,
                'webpush' => $webpushSettings,
                'fcm_options' => $fcmOptions
            ]);

            $messaging = app('firebase.messaging');

            try {

                $sendingInfo = $messaging->send($message);

                Log::channel('merlin_debug')->info('$sendingInfo:');
                Log::channel('merlin_debug')->info($sendingInfo);

            } /*catch (FirebaseException $error) {//NotFound error is more explicit
                //FirebaseException error
                Log::channel('merlin_debug')->info('FirebaseException error');

                Log::channel('merlin_debug')->info('error message:');
                Log::channel('merlin_debug')->info($error);

            } */catch (InvalidArgument $error) {
                //InvalidArgument error
                Log::channel('merlin_debug')->info('InvalidArgument error');

                Log::channel('merlin_debug')->info('error message:');
                Log::channel('merlin_debug')->info($error);

                //FIX_THIS_SOON WE NEED TO BE SURE ABOUT WHAT ACTION TO TAKE HERE BECAUSE THE ERRORS ARE AMBIGUOUS, WE MIGHT DELETE A TOKEN WHEN THE ERROR IS RELATED TO SOMETHING ELSE, THINK ABOUT THIS CAREFULLY

            } catch (InvalidMessage $error) {
                //InvalidMessage error
                Log::channel('merlin_debug')->info('InvalidMessage error');

                Log::channel('merlin_debug')->info('error message:');
                Log::channel('merlin_debug')->info($error);

                //FIX_THIS_SOON WE NEED TO BE SURE ABOUT WHAT ACTION TO TAKE HERE BECAUSE THE ERRORS ARE AMBIGUOUS, WE MIGHT DELETE A TOKEN WHEN THE ERROR IS RELATED TO SOMETHING ELSE, THINK ABOUT THIS CAREFULLY

            } catch (NotFound $error) {
                //NotFound error, token is not registered to the project (any more) delete the token
                Log::channel('merlin_debug')->info('token is not registered to the project (any more) delete the token');

                Log::channel('merlin_debug')->info('error message:');
                Log::channel('merlin_debug')->info($error);

                //remove this from the list of endpoints for this user
                Log::channel('merlin_debug')->info('remove this from the list of endpoints for this user');

                //check the endpoint
                $endpointOperations = new EndpointOperations();

                $endpointOperationsResponse = $endpointOperations->delete($endpointUID);

                if ($endpointOperationsResponse['status'] == 'success') {
                    //we are good, endpoint was deleted
                    Log::channel('merlin_debug')->info('we are good, endpoint was deleted');
                } else {
                    //bad news, endpoint was not deleted successfully
                    Log::channel('merlin_debug')->info('bad news, endpoint was not deleted successfully');
                }

            } catch (Exception $error) {
                //generic error
                Log::channel('merlin_debug')->info('generic error');

                Log::channel('merlin_debug')->info('error message:');
                Log::channel('merlin_debug')->info($error);

            }

        } else {

            //do nothing for now, there are no other push notifications service provider in this system that we can handle

        }

    }

}
jeromegamez commented 2 years ago

Hey Jerome, I meant in the sense that if I went into the package file and changed the minimum version. Would it work you think? Or would that version break the package because it is so different than 7.4?

I think it would break your application because PHP 7.4 introduced typed properties, which aren't supported in PHP 7.3 :/

Thank you for sharing your composer.json - one thing I noticed is that you specified "kreait/laravel-firebase": "1.3", - although it will not help with the current challenge, it should be save to specify it as "kreait/laravel-firebase": "^1.3", because this would upgrade the package to the latest 1.x version (= 1.5).

I'm working on an example of how you can use two Firebase projects in the same application - thanks for the info that you're only using the messaging component, this will make it easier to whip it up 😅

nicolasvahidzein commented 2 years ago

Ok understood! Thanks a ton!.

jeromegamez commented 2 years ago

Alright, I haven't tested this, but I hope at least the general direction is already the right one - and if that does work, we can talk about optimizing it further.

Here we go…

First, create a new file in your config directory named my_firebase.php with the following contents (adapted to your project)

<?php

return [
    'projects' => [
        'project_1' => [
            'credentials' => env('PROJECT_1_FIREBASE_CREDENTIALS'),
        ],
        'project_2' => [
            'credentials' => env('PROJECT_2_FIREBASE_CREDENTIALS'),
        ],
    ],
    'cache_store' => env('FIREBASE_CACHE_STORE', 'file'),
];

Then create a new Service Provider named MyFirebaseServiceProvider in app/Providers:

<?php

namespace App\Providers;

use Kreait\Firebase;

class MyFirebaseServiceProvider extends \Illuminate\Support\ServiceProvider
{
    public function boot()
    {
        $firebaseConfig = config('my_firebase');
        $cache = $this->app->make('cache')->store($firebaseConfig['cache_store']);

        foreach ($firebaseConfig as $projectId => $projectConfig) {
            $this->registerProject($projectId, $projectConfig, $cache);
        }
    }

    /**
     * @param string $projectId
     * @param array $config
     * @param \Illuminate\Contracts\Cache\Repository $cacheStore
     * @return void
     */
    private function registerProject($projectId, $config, $cacheStore)
    {
        $credentials = $this->resolveCredentials($config['credentials']);

        $factory = (new Firebase\Factory())
            ->withServiceAccount($credentials)
            ->withVerifierCache($cacheStore);

        $this->app->singleton('firebase.'.$projectId.'.auth', function ($app) use ($factory) {
            return $factory->createAuth();
        });

        $this->app->singleton('firebase.'.$projectId.'.messaging', function ($app) use ($factory) {
            return $factory->createMessaging();
        });
    }

    private function resolveCredentials(string $credentials): string
    {
        $isJsonString = strpos($credentials, '{') === 0;
        $isAbsoluteLinuxPath = strpos($credentials, '/') === 0;
        $isAbsoluteWindowsPath = strpos($credentials, ':\\') !== false;

        $isRelativePath = !$isJsonString && !$isAbsoluteLinuxPath && !$isAbsoluteWindowsPath;

        return $isRelativePath ? $this->app->basePath($credentials) : $credentials;
    }
}

After this, you should be able to use app('firebase.project_1.messaging') and app('firebase.project_2.messaging') throughout your app 🤞

nicolasvahidzein commented 2 years ago

Bad news, i followed the steps exactly but not getting any notifications.

Is there a way to find out where the error happened?

$message = new RawMessageFromArray([
    'token' => $deviceToken,
    //'name' => $name,
    //'topic' => $topic,
    //'condition' => $condition,
    'notification' => $notificationPayload,
    'data' => $data,
    'android' => $androidSettings,
    'apns' => $apnsSettings,
    'webpush' => $webpushSettings,
    'fcm_options' => $fcmOptions
]);

$messaging = null;

if ($endpoint->foreignUID_type == 'client') {
    $messaging = app('firebase.client_mobile_app.messaging');
} else {
    $messaging = app('firebase.admin_mobile_app.messaging');
}

$sendingInfo = $messaging->send($message);
nicolasvahidzein commented 2 years ago

Don't I have to call the MyFirebaseServiceProvider class somewhere?

$messaging = app('firebase.messaging') which is now app('firebase.project_1.messaging') might be the issue no?

nicolasvahidzein commented 2 years ago

I indeed found this in the logs:

Class firebase.client_mobile_app.messaging does not exist

jeromegamez commented 2 years ago

Aaah, right, I think you have to add it to the 'providers' array in the config/app.php file

sorry, I didn't try the changes myself because I currently don't have PHP 7.3 and a Laravel 5.8 project around 🙈

nicolasvahidzein commented 2 years ago

No that's my job. I'm ecstatic you are helping. Don't sweat it.

Do i keep the default firebase.php in config?

nicolasvahidzein commented 2 years ago

Still not working. I added it to the app/config.php

        //Application Service Providers
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
    App\Providers\RouteServiceProvider::class,
    App\Providers\MyFirebaseServiceProvider::class,

I have an error on this line:

$credentials = $this->resolveCredentials($config['credentials']);

It says undefined index: credentials

nicolasvahidzein commented 2 years ago

001

nicolasvahidzein commented 2 years ago

Error 100% is coming from that credentials line. Not sure why. Very strange.

jeromegamez commented 2 years ago

Give me a bit, I'll set up a project and try to reproduce it. 🤞

nicolasvahidzein commented 2 years ago

DON'T STRESS. I figured it out.

There was a tiny mistake in the boot function:

        $firebase = config('my_firebase');

        $firebaseConfig = $firebase['projects'];

        $cache = $this->app->make('cache')->store($firebase['cache_store']);

        foreach ($firebaseConfig as $projectId => $projectConfig) {

            $this->registerProject(
                $projectId,
                $projectConfig,
                $cache
            );

        }
nicolasvahidzein commented 2 years ago

YOU ARE A GENIUS AND AN AMAZING MAINTAINER!!!!!

You fixed everything. I am definitely supporting you big time when this app takes off.

A THOUSAND THANK YOU!!!!

jeromegamez commented 2 years ago

Dangit, I just wanted to send you THE SAME MESSAGE!!! 😂

But I can add something - if this is working fine with you, and since you now have your own custom integration, you don't actually need the Laravel package anymore 😅

I published my implementation at https://github.com/jeromegamez/laravel58-with-firebase for reference.

jeromegamez commented 2 years ago

But the important part is that you made it work 🚀 , glad I could help!

nicolasvahidzein commented 2 years ago

I did nothing, you did the heavy lifting. I pushed you over the edge!! THANKS!!!!!!!!!!!!