1. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

Firebase change credentials at run time from database on Laravel

Discussão em 'Outras Linguagens' iniciado por Husam Al-Miyah, Outubro 1, 2024 às 06:03.

  1. I’m working on a multi-organization Laravel application that uses Firebase Cloud Messaging (FCM) to send notifications. Each organization has its own FCM credentials because each organization's users use a separate app with a different SenderId.

    I’m using the Firebase PHP SDK ("kreait/firebase-php": "6.3.1") and have overridden Laravel’s Notifiable trait to dynamically switch the FCM credentials at runtime, based on the organization associated with the user receiving the notification.

    Here’s how I’ve implemented the custom trait:

    Custom HasNotifiable Trait


    // src\Domain\Auth\Models\Concerns\HasNotifiable.php

    trait HasNotifiable
    {
    use Notifiable;

    /**
    * Send the given notification.
    *
    * @param mixed $instance
    * @return void
    */
    public function notify($instance)
    {
    $this->handleOrganizationNotification();
    app(Dispatcher::class)->send($this, $instance);
    }

    /**
    * Send the given notification immediately.
    *
    * @param mixed $instance
    * @param array|null $channels
    * @return void
    */
    public function notifyNow($instance, array $channels = null)
    {
    $this->handleOrganizationNotification();
    app(Dispatcher::class)->sendNow($this, $instance, $channels);
    }

    /**
    * Custom method to handle organization-specific notification logic.
    *
    * @return void
    */
    protected function handleOrganizationNotification()
    {
    try {
    $organization = $this->getOrganization();

    if ($organization && !is_null($organization->fcm_credentials)) {
    Config::set('firebase.projects.app.credentials.file', $organization->fcm_credentials);
    } else {
    Config::set('firebase.projects.app.credentials.file', config('firebase.projects.app.credentials.fallback-file'));
    }
    } catch (\Exception $e) {
    Log::error('Failed to set FCM credentials: '.$e->getMessage());
    }
    }

    protected function getOrganization()
    {
    if (method_exists($this, 'organization') && $this instanceof User) {
    return $this->organization;
    }

    if (method_exists($this, 'authable') && $this->authable instanceof User) {
    return $this->authable?->organization;
    }

    return null;
    }
    }

    Firebase Configuration


    Here’s the relevant part of my Firebase configuration (config/firebase.php):

    return [
    'default' => env('FIREBASE_PROJECT', 'app'),

    'projects' => [
    'app' => [
    'credentials' => [
    'file' => env('FIREBASE_CREDENTIALS', env('GOOGLE_APPLICATION_CREDENTIALS')),
    'fallback-file' => env('FIREBASE_CREDENTIALS', env('GOOGLE_APPLICATION_CREDENTIALS')),
    ],
    ],
    ],
    ];

    User Model


    In the User model, I’ve added the custom trait (HasNotifiable), along with others:

    class User extends Authenticatable
    {
    use HasApiTokens, HasDevices, HasSocial, MobileActivation, SoftDeletes;
    use HasConversations, HasDatabaseNotifications, HasFactory;
    use HasNotifiable, HasSegment, HasOrganization;
    }

    Problem


    Here’s the scenario:

    • I have two organizations (Org1 and Org2), each with its own FCM credentials (fcm_credentials) set in the database.
    • When I send a notification from Org1, the first notification fails with an error:
      • Unable to determine the Firebase Project ID
      • Sometimes, it also gives a SenderId mismatch error.
    • The second notification from Org1 is sent successfully.
    • When Org2 sends a notification, the same issue happens—the first notification fails, and the second succeeds.

    It seems like the first notification doesn’t correctly use the dynamic FCM credentials, but the second one does.

    Question


    What could be causing the issue where the first notification fails with a SenderId mismatch or Unable to determine the Firebase Project ID error, but subsequent notifications succeed? How can I ensure that the correct FCM credentials are used for each notification on the first attempt?


    Notes:

    • I’m using Config::set to change the FCM credentials dynamically at runtime.
    • The issue appears to be related to switching between different FCM credentials for different organizations in the same process.

    Continue reading...

Compartilhe esta Página