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ží.
Vytvoření nového projektu
Formulář pro vyplnění jména projektu
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.
Vytvoření nové aplikace
Formulář pro vyplnění jména aplikace
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
).
Přehled aplikací
Přehled aplikací - nastavení
Nastavení - obecné
Nastavení - zprávy
Nastavení - varování
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í.
- 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.
- 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+)
- 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:
- Verze systému musí být 16.1+
- Aplikace musí v root složce projektu (obvykle
/www
) obsahovatmanifest.json
(následující příklad obsahuje nutné - 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"
}
- 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é
Nastavení - Safari
Nastavení - Pokročilé
Nastavení - Experimentální funkce
Nastavení - Push Api
Web - Pro přidání aplikace na plochu klikněte na spodní tlačítko pro sdílení a přidejte aplikaci na plochu
Web - Přidání na plochu
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.