You are using an outdated browser. For a faster, safer browsing experience, upgrade for free today.

Loading...

Blog

Zde najdete zajímavé články ze světa IT.
Chcete napsat článek? Zapojte se.

Firebase FCM PHP/Nette tutoriál

zpět na kategorii Tutoriály - Před rokem, Autor: Michaela Petřivalská


V tomto článku si krok za krokem ukážeme, jak použít Firebase (FCM) k rozesílání push notifikací ve vašich Nette projektech.



Tento tutoriál ti vysvětlí jak využít Firebase (FCM) v tvém Nette projektu.

1. Obecné

Tento návod bude ukazovat, jak snadno lze zakomponovat Firebase (FCM) do vašich Nette projektů. Cílem je začít posílat hromadné notifikace uživatelům, kteří souhlasili se zasíláním notifikací. Pro zakomponování dalších funkčností, jako rozesílání zpráv podle topiců, doporučuji projít i dokumentaci Firebase (FCM) případně dokumentaci Firebase Admin SDK for PHP, následující návod je jen zkráceným a neuplným výtahem z obou dokumentací a je specifický pro Nette.

2. Firebase

Nejprve musíme zaregistrovat sebe, projekt i aplikaci na Firebase Console, k tomu nám postačí Google účet. Hned po registraci a prvním přihlášení nám vyskočí možnost vytvoření nového projektu. Stačí vyplnit jméno projektu, to nemusí být unikátní, těsně pod ním je id projektu, které se nastavuje automaticky, ale můžeš ho pozměnit (to už unikátní být musí). Poté zvolíme zda bude projekt využívat Google analytics a projekt se založí.

Screenshot of creating project

Vytvoření nového projektu

Screenshot of creating project - set name

Formulář pro vyplnění jména projektu

Screenshot of creating project - allow Google

Zde můžeme zadat zda chceme využívat Google analytics

V tento moment bys měl mít projekt v pořádku založen a je zapotřebí založit webovou aplikaci v rámci projektu. Opět bude nutné nastavit jméno, ale více pro vytvoření není potřeba. Po zadání názvu a přechodu na další krok uvidíme js kód, který obsahuje nastavení pro Firebase, které budeme potřebovat dále. Kdykoli se k němu ale dostaneme z nastavení, není tedy potřeba si ho nyní ukládat.

Screenshot of creating app

Vytvoření nové aplikace

Screenshot of creating app - set name

Formulář pro vyplnění jména aplikace

Screenshot of creating app - overview

Nastavení

Nyní na úvodní stránce uvidíme přehled aplikací. Vše co nás zajímá pro další postup je v nastavení. Budeme potřebovat Firebase config (sekce General), Vapid Key (public key) (sekce Cloud messaging) a Firebase Admin SDK private key (sekce Service accounts).

Firebase Admin SDK private key musí být uložen mimo hlavní repozitáře, je jen pro vaše použití a při ztrátě nelze obnovit, ale může být vygenerován nový. Doporučuji uložit mimo document root (obvykle složku /www).

Screenshot of creating app - overview

Přehled aplikací

Screenshot of creating app - overview - setting

Přehled aplikací - nastavení

Screenshot of creating app setting - general

Nastavení - obecné

Screenshot of creating app setting - cloud messaging

Nastavení - zprávy

Screenshot of creating app setting - warning

Nastavení - varování

Screenshot of creating app setting - service accounts

Nastavení - účty

3. Frontend

Na frontendu budeme chtít získávat tokeny uživatelů, které slouží jako adresa pro následující notifikace. Abychom je získali musíme si krom dalších věcí vyžádat povolení od uživatele o zasílání notifikací. Tady může nastat pár komplikací.

  1. Některé prohlížeče (například Google), pokud uživatel často odmítá povolení se zasíláním upozornění, sám to na pozadí zamítne.
  2. iOS bez několika mezikroků ani neumožní uživateli si notifikace zapnout (návod pro uživatele je v sekci iOS - funguje jen pro systémy 16.1+)
  3. Některé operační systémy mají v nastavení možnost nastavení notifikací - toto nastavení je potřeba mít na povolení notifikací

Prvním krokem je importovat Firebase knihovny:

<script src="https://www.gstatic.com/firebasejs/10.8.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/10.8.0/firebase-messaging-compat.js"></script>

Následně se můžeme pustit do našeho js kódu - ve funkci sendTokenToServer() využívám $.nete.ajax, tato funkce slouží k odeslání tokenu uživatele na server, je na vás jak si ji implementujete. Dále využívám jQuery pro namapování onClick metody na tlačítko - kvůli iOS nastavení je nutné mít možnost nastavení souhlasu s notifikacemi i přes tlačítko - více k problémům s iOS a dalšími produkty od Apple najdete v sekci iOS - opět je možné si tuto funkci přizpůsobit tak, aby vám vyhovovala, klíčové body jsou popsány níže.

// Firebase config - lze získat v nastavení v sekci general, viz výše
const firebaseConfig = {
   apiKey: "AIza*********************************",
   authDomain: "fir-testmipe.firebaseapp.com",
   projectId: "fir-testmipe",
   storageBucket: "fir-testmipe.appspot.com",
   messagingSenderId: "**********",
   appId: "1:163******************************"
};

//public key, který lze vygenerovat v nastavení v sekci Cloud messaging 
//jeho privátní klíč není potřeba nikam ukládat, lze se k němu kdykoli dostat z nastavení
const vapidKey = 'BM***************************************************';

//inicializace Firebase a Messagingu
const app = firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();

//onClick metoda na vyžádání souhlasu s notifikacemi
$(document).on('click', '#request-permission-button', function() {
    //níže popisuji předání url přes data-url u html prvku
    let url = $(this).data('url');
    
    //Ověří zda prohlížeč podporuje desktop notifikace
    if (!("Notification" in window)) {
        alert("This browser does not support desktop notification");
        return;
    }
    
    if (Notification.permission !== "granted" && Notification.permission !== "denied") {
       //pokud ještě klient notifikace nepovolil ani nezakázal, vyžádáme si povolení
        Notification.requestPermission()
            .then((permission) => {
                if (permission !== 'granted') {
                    //kód, který se provede, pokud uživatel notifikace nepovolí
                    console.log('Unable to get permission to notify.');
                    return;
                }

                //kód, který se provede, pokud uživatel notifikace povolí
                console.log('Notification permission granted.');
                //získání tokenu
                messaging.getToken({ vapidKey: vapidKey })
                    .then(function (token) {
                        if(token) {
                            console.log(token);
                            //poslání tokenu na server
                            sendTokenToServer(token, url);
                        }
                    }).catch((err) => {
                        console.log(err);
                    });
            });
    }
});

//pošle token do handle metody
function sendTokenToServer(token, url) {
    $.nette.ajax({
        url: url,
        method: 'POST',
        data: {
            token: token
        }
    });
}

//inicializuje ověření povolení notifikací => nefunguje na iOS
$('#request-permission-button').click();

Tlačítku v html kódu jen nastavíme id (pro nastavení event metody) a data-url (pro správné volání handle metody)

<button id='request-permission-button'
    data-url="{link saveToken!}">Request Permission
</button>

Nyní by mělo hotovo vše pro Frontend, ale protože Apple má důslednější bezpečnostní prvky tak, aby vše fungovalo i na iOS a ostatních produktech od Apple, je potřeba vytvořit manifest.json, postup najdete v sekci iOS. Pokud by jste chtěli nastavit cokoli dalšího, tak lze vše navíc dohledat ve výše zmíněných dokumentacích.

4. Backend

Samotné posílání tokenu na server následně vyřeší handle metoda, jak bylo zmíněno v předchozí části:


    public function handleSaveToken(): void
    {
        //získání tokenu
        $token = $this->getHttpRequest()->getPost('token');

        //ověření zda již token v Db existuje
        if($this->userTokenRepository->tokenExists($token)) {
            return;
        }

        //vytvoření záznamu v Db
        $userToken = $this->userTokenRepository->createEntity();
        assert($userToken instanceof UserToken);
        $userToken->token = $token;

        $this->userTokenRepository->persistAndFlush($userToken);
    }

Je možné využít vlastní implementaci OAuth2 ověření a zasílání zpráv, pro zjednodušení doporučuji využít knihovnu Firebase Admin SDK pro PHP.

Pro tento krok si potřebujeme uložit privátní klíč, který si můžeme vygenerovat v nastavení, v sekci Service Accounts

Firebase Admin SDK private key musí být uložen mimo document root (obvykle složku /www), je jen pro vaše použití a při ztrátě nelze obnovit, ale může být vygenerován nový.

//cesta k privátnímu klíči
$authConfig = $projectDir . '/fir-testmipe-firebase-adminsdk-go6jt-e847710.json';

//vytvoříme si továrnu pomocí Firebase Admin SDK pro PHP
$kreaitFactory = (new Factory())
            ->withServiceAccount($authConfig)
            ->withAuthTokenCache($this->cacheItemPool);
            //pokud chceme cachovat OAuth2 token po svém potřebujeme Cache využívající interface dle PSR standardů

//vyřeší OAuth2 authorizaci
$kreaitFactory->createAuth();

//vytvoří 
$messaging = $kreaitFactory->createMessaging();

//nastavíme si titulek, tělo, obrázek, iconu, vše co potřebujeme

$notification = Notification::fromArray([
   'title' => 'Titulek',
   'body' => 'Zpráva, která se zobrazí uživatelům',
   'image' => 'https://bitbucket.org/tondajehlar/blogtondajehlar/raw/master/assets/images/tutorials/tutorial_thumbnail.png',
]);

//vytvoříme si individuální nastavení podle platformy - podrobnější info lze najít v dokumentacích
//Nastavení webu - fcm_options - link je nutné nastavení, pokud chceme po kliknutí na notifikaci přesměrovávat
$webPushConfig = WebPushConfig::fromArray([
   'fcm_options' => [
       'link' => 'https://testa.michaelapetrivalska.com/',
   ],
]);

//nastavení pro android
$androidConfig = AndroidConfig::fromArray([
   'ttl' => '3600s',
   'priority' => 'normal',
]);

//nastavení pro Apple Push Notification service (APNs)
$apnsConfig = ApnsConfig::fromArray([
   'headers' => [
       'apns-priority' => '10',
   ],
]);

//vytvoření zprávy
$message = CloudMessage::new()
            ->withWebPushConfig($webPushConfig)
            ->withAndroidConfig($androidConfig)
            ->withApnsConfig($apnsConfig)
            ->withNotification($notification);

//tokeny na které budeme zasílat notifikace
$tokens = array_values($this->userTokenRepository->findAll()->fetchPairs('id', 'token'));

//odeslání zprávy na všechna vybraná registrovaná zařízení
$sendReport = $messaging->sendMulticast($message, $tokens);

V $sendReport budeme mít následně veškeré info o jednotlivých zprávách, zda byly na příslušné tokeny doručeny, zda token ještě existuje, zda bylo vše v pořádku atp.

5. iOS

Bohužel iOS má speciální zabezpečení a pro fungování push notifikací je potřeba splnit několik podmínek:

  1. Verze systému musí být 16.1+
  2. Aplikace musí v root složce projektu (obvykle /www) obsahovat manifest.json (následující příklad obsahuje nutné
  3. minimum, je možné nastavit více věcí). Pokud si nevíte rady, můžete vyzkoušet manifest generátor. Platí i pro další Apple produkty
{
  "gcm_sender_id": "<messagingSenderId - firebase config>",
  "display": "standalone"
}
  1. Klient musí mít správně nastavený telefon
    • V nastavení - v Safari musí být povoleny pop-upy
    • V nastavení - v experimentálních funkcích musí být povoleno pushAPI
    • Klient si musí přidat aplikaci na plochu, spustit aplikaci z plochy a kliknout manuálně na tlačítko pro povolení notifikací
    • Následně může opět vypnout zobrazování pop-upů, ale pushAPI musí zůstat povolené

Settings iOS - Safari

Nastavení - Safari

Settings iOS - Advanced

Nastavení - Pokročilé

Settings iOS - Experimental

Nastavení - Experimentální funkce

Settings iOS - Push API

Nastavení - Push Api

Settings iOS - Web

Web - Pro přidání aplikace na plochu klikněte na spodní tlačítko pro sdílení a přidejte aplikaci na plochu

Settings iOS - Web

Web - Přidání na plochu

Settings iOS - Web

Web - Vyžádání oprávnění - je nutné mít aplikaci spuštěnou z plochy

Pokud bude aplikace z plochy odstraněna - automaticky se zruší klientův souhlas s push notifikacemi pro vaší aplikaci

6. Závěr

Teď by vaše aplikace měly být schopné rozesílat hromadné push notifikace. Jak jste zjistili, není na tom nic složitého.