#Solved: A new FCM token every time the app is closed and reopened on IOS

1 messages · Page 1 of 1 (latest)

south glade
#

View

<!doctype html>
<html lang="en">
<head>
    <script>
        const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
        document.documentElement.setAttribute("data-bs-theme", isDarkMode ? "dark" : "light");
    </script>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    {{-- Vite load css and js --}}
    @vite('resources/css/app.css')
    @vite('resources/js/app.js')
</head>
<body>

<div class="container">
    <div class="row">
        <div class="col-12">
            {{ $slot }}
        </div>
    </div>
</div>
<x-push-notifications></x-push-notifications>
</body>
</html>
#

Component

@use(Native\Mobile\Events\PushNotification\TokenGenerated)

<script>
    document.addEventListener('DOMContentLoaded', function () {
        Native.on(@js(TokenGenerated::class), (token) => {
            console.log('INFO: Push token generated:', token.token);

            fetch('/firebase-cloud-messaging/push-token', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': @json(csrf_token())
                },
                body: JSON.stringify({
                    token: token.token,
                }),
            })
                .then(response => response.json())
                .then(data => console.log('Push token stored:', data))
                .catch(error => console.error('Failed to store push token:', error));
        });
    });
</script>
#

Controller

<?php

namespace App\Http\Controllers;

use App\Helper\Helper;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
use Native\Mobile\Facades\PushNotifications;

/**
 * Class PublicProfileController
 * @package App\Http\Controllers
 */
class PublicProfileController extends Controller
{
    /**
     * @param Request $request
     * @return View|JsonResponse
     * @throws ConnectionException
     */
    public function index(Request $request): view|JsonResponse
    {
        // Collect the data
        $agents = Helper::agentsJson();

        // Check for errors
        if (isset($agents['error'])) {
            return response()->json($agents, 403);
        }

        // Check for errors
        if (!filled($agents)) {
            return response()->json($agents, 404);
        }

        // Get locale from URL
        $locale = $request->query('lang') ?? 'en';
        $authUser = view()->shared('auth_user');
        
        if ($authUser) {
            $locale = $authUser[$authUser['role']]['language'] ?? 'en';
        }

        // Enroll for push notifications
        PushNotifications::enrollForPushNotifications();
        $test = PushNotifications::getPushNotificationsToken();

        Log::info('Push token: ', [$test]);

        // Return view
        return view('public.profile.index', [
            'agents' => Helper::agentsJson(),
            'locale' => Helper::translation($locale),
        ]);
    }
}
#

Storing the token on the remote server works using laravel sanctum.
But creating a new token every time the app closes completely and is reopened, is not correct, is it (PushNotifications::enrollForPushNotifications(); fires everytime the app opens). For some reason i think i am missing something to handle the logic in app when it already has a FCM token or not. Would love to hear some thoughts on how to handle this logic. It does make sense to create a new token on a fresh app installation. But not on every restart of the app does it. Cheers

south glade
#

Solved: A new FCM token every time the app is closed and reopened on IOS

#

Problem is solved. When the app opens the first time it generates a unique app id. This is stored in the local storage. Now every time the app opens and is requesting a new FCM token I'll send that FCM token to the server along side the unique app id. On the server side it's insertOrUpdate the push token for this device. This prevents multiple push token entries from the same device

<?php

namespace App\Http\Controllers;

use App\Helper\Helper;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\View\View;
use Native\Mobile\Facades\PushNotifications;
use Native\Mobile\Facades\System;

/**
 * Class PublicProfileController
 * @package App\Http\Controllers
 */
class PublicProfileController extends Controller
{
    /**
     * @param Request $request
     * @return View|JsonResponse
     * @throws ConnectionException
     */
    public function index(Request $request): view|JsonResponse
    {
        // Collect the data
        $agents = Helper::agentsJson();

        // Does the client app id exist.
        $clientAppIdExists = Storage::exists(config('apptabai.client_app_id'));
        if (!$clientAppIdExists) {
            Storage::put(config('apptabai.client_app_id'), Str::random(128));
        }

        // Enroll for a push token
        if (System::isIos()) {
            PushNotifications::enrollForPushNotifications();
        } elseif (System::isAndroid()) {
            PushNotifications::getPushNotificationsToken();
        }

        // Return view
        return view('public.profile.index', [
            'agents' => Helper::agentsJson(),
            'locale' => Helper::translation($locale),
        ]);
    }
}
#

On the front-end send the FCM token + client app id to the server

@use(Native\Mobile\Events\PushNotification\TokenGenerated)
<script>
    document.addEventListener('DOMContentLoaded', function () {
        Native.on(@js(TokenGenerated::class), (token) => {
            console.log('INFO: Push token generated:', token.token);

            fetch('/firebase-cloud-messaging/push-token', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': @json(csrf_token())
                },
                body: JSON.stringify({
                    manager_id: @json(config('apptabai.manager_id')),
                    client_app_id: @json(Storage::get(config('apptabai.client_app_id'))),
                    token: token.token,
                }),
            })
                .then(response => response.json())
                .then(data => console.log('Push token stored:', data))
                .catch(error => console.error('Failed to store push token:', error));
        });
    });
</script>

timber ingot
south glade
# timber ingot

I have no problems with

{{-- Vite load css and js --}}
@vite('resources/css/app.css')
@vite('resources/js/app.js')

In ios.