7.4 KiB
Meldingen op de telefoon
Als er een bericht voor iemand wordt bezorgd, hoort zijn telefoon dat te laten weten - ook als de app dicht is. Daarvoor is Firebase Cloud Messaging van Google nodig; een andere weg is er op Android niet.
De applicatie is er klaar voor. Wat er nog moet gebeuren is een Firebase-project aanmaken en twee bestanden op de juiste plek zetten. Aan de code hoeft niets te veranderen: het csproj gaat vanzelf aan zodra het eerste bestand er staat.
Wat er al werkt
| Onderdeel | Waar |
|---|---|
| Toestellen bijhouden | tabel toestellen, MeldingService |
| Aanmelden vanuit de app | bij elk inloggen en elke hervatte sessie |
| Afmelden bij uitloggen | zodat de volgende gebruiker op die telefoon niet jouw meldingen krijgt |
| Versturen bij bezorging | MessageService.DeliverAsync |
| Praten met Google | FirebasePush, met een zelfgeschreven ondertekening |
| Opruimen van dode kenmerken | een toestel dat Google niet meer kent wordt meteen afgemeld |
Zonder servicesleutel gebeurt er niets en werkt alles gewoon door - er gaan alleen geen meldingen uit.
Wat er bewust níét in een melding staat: de inhoud. Een melding verschijnt op een scherm dat ook zichtbaar is als de telefoon op tafel ligt. Er staat alleen dat er iets klaarstaat en van wie. Daar is een controle voor in de zelftest.
Stap 1: het Firebase-project
- Ga naar console.firebase.google.com en maak een project, bijvoorbeeld MijnBesluit. Google Analytics kun je overslaan.
- Voeg een Android-app toe met pakketnaam
nl.mijnbesluit.app- precies zoals hij inMijnBesluit.App.csprojbijApplicationIdstaat. - Download
google-services.jsonen zet hem insrc\MijnBesluit.App\Platforms\Android\.
Een Play Console-account is hier niet voor nodig; Firebase is gratis en staat los van de Play Store.
Stap 2: niets
Dit stond hier vroeger als een handmatige aanpassing van het csproj. Dat is nu niet meer nodig:
in MijnBesluit.App.csproj staat een blok dat zichzelf aanzet zodra google-services.json er
staat. Het haalt dan het package Xamarin.Firebase.Messaging erbij, koppelt het json-bestand,
en zet de schakelaar FIREBASE aan die bij de #if in Toestelmeldingen.cs hoort.
Staat het bestand er niet, dan gebeurt er niets en bouwt het project gewoon. Dat is met opzet: er is nu geen stap die je een keer kunt overslaan, en het project blijft te bouwen op een machine waar dat bestand niet staat.
Het versienummer in dat blok (125.1.1.1, bij net10.0-android) moet passen bij de
werkbelasting op je machine. Klaagt de build over versies, kijk dan in NuGet welke bij jouw
.NET-versie hoort en pas alleen dat nummer aan.
In hetzelfde blok staan vijf AndroidX-packages met een versienummer erbij. Die horen niet bij
Firebase zelf, maar lossen een botsing op: Firebase vraagt om oudere .Ktx-packages, terwijl
MAUI de bijbehorende basispackages al nieuwer binnenhaalt. Sinds Fragment 1.9.0 zitten de
Kotlin-uitbreidingen in het hoofdpackage, dus kwam dezelfde klasse twee keer binnen en brak de
build bij het dexen (Type androidx.fragment.app.FragmentManagerKt is defined multiple times).
Komen de NU1608-waarschuwingen ooit terug, dan heeft een nieuwere MAUI de basispackages weer
opgehoogd: zoek in NuGet de bijpassende .Ktx-versie op en hoog die nummers mee op. Weghalen
lost het niet op, dan komt de dubbele klasse terug.
Na het wijzigen van die versies: gooi src\MijnBesluit.App\obj en bin weg voordat je opnieuw
bouwt. In obj staan de uitgepakte Java-bibliotheken van de vorige build, en die worden niet
altijd opgeruimd.
Stap 3: de servicesleutel op de server
- In Firebase: Projectinstellingen > Serviceaccounts > Nieuwe persoonlijke sleutel genereren. Er wordt een json-bestand gedownload.
- Zet dat op de server als
C:\MijnBesluitData\keys\firebase.json. - Zet in
C:\MijnBesluitData\appsettings.secrets.json:
"Push": {
"ServiceAccountFile": "C:\\MijnBesluitData\\keys\\firebase.json"
}
Restart-Service MijnBesluitSocket.
Dat bestand is een sleutel tot je Firebase-project. Bewaar het net zo zorgvuldig als
masterkey.json en zet het nooit in de publicatiemap - die wordt bij elke publicatie
overschreven, en erger: dan staat hij in het zip-bestand dat je rondstuurt.
In het logboek van de service staat bij het opstarten of het gelukt is:
Meldingen staan aan voor Firebase-project mijnbesluit-...
Stap 4: controleren
- App opnieuw installeren en inloggen. Android vraagt nu toestemming voor meldingen - die
vraag komt van
Permissions.PostNotifications, verplicht sinds Android 13. - Ga naar Mijn profiel en druk op "Stuur me een proefmelding". Dat kan ook op de website, bij Mijn profiel onder Meldingen op je telefoon.
Die knop loopt de hele keten langs en zegt waar het op vastloopt:
| Wat er staat | Wat eraan mankeert |
|---|---|
| "Op de server staat geen servicesleutel voor Firebase" | stap 3 is niet gedaan, of het pad klopt niet |
| "Er is geen toestel aangemeld" | de app heeft geen kenmerk; zie Als er niets komt hieronder |
| "Verstuurd naar je toestel" en je ziet niets | meldingen staan op de telefoon zelf uit |
| "Google nam de melding niet aan" | het kenmerk is verlopen; opnieuw inloggen in de app |
| Je ziet de melding | klaar |
Hij gaat alleen naar je eigen toestellen. Iemand anders een melding kunnen sturen zou een manier zijn om mensen lastig te vallen; daar is een controle voor in de zelftest.
Wil je het echte pad ook een keer zien: zet vanaf de website een bericht voor jezelf klaar met bezorging meteen. De achtergrondtaak van de SocketServer bezorgt het binnen een kwartier, en dan hoort de melding vanzelf te verschijnen.
Als er niets komt
- Geen regel in
toestellen- de app krijgt geen kenmerk. Meestal ontbreektgoogle-services.jsonin de APK die op het toestel staat (is hij ná het bouwen toegevoegd, bouw dan opnieuw), of heeft de gebruiker de toestemmingsvraag weggeklikt.
SELECT id, user_id, platform, naam, laatst_gezien FROM toestellen;
- Wel een regel, geen melding - kijk in het logboek van de service. Staat er "Google gaf geen toegangstoken", dan klopt de servicesleutel niet. Staat er "Melding niet afgeleverd", dan zegt Google waarom.
- "Verstuurd naar je toestel", maar niets te zien terwijl de app openstaat - Android zet een
melding alleen zelf in de balk als de app op de achtergrond staat. Staat de app open, dan geeft
Android hem door aan
MeldingsdienstinPlatforms\Android, en die toont hem. Ontbreekt die klasse, of is hij niet als dienst aangemeld, dan verdwijnt de melding geruisloos. Daarom gaan titel en tekst twee keer mee in het bericht: in hetnotification-deel voor Android zelf, en in hetdata-deel voor de app. ZieFirebasePush.StuurAsync. - Werkte eerst, nu niet meer - het kenmerk van Firebase verandert af en toe vanzelf, bijvoorbeeld na het terugzetten van een back-up. De app meldt zich daarom bij elke start opnieuw aan; werkt dat niet, dan komt de app niet langs het inloggen.
Wat hier nog niet in zit
- iOS. Daar loopt het via APNs, met een sleutel uit het Apple Developer Program (€99 per jaar). Firebase kan dat doorgeven, dus de serverkant blijft hetzelfde.
- Meldingen bij andere gebeurtenissen. Nu alleen bij een bezorgd bericht. Een overlijdens-
melding of een uitnodiging zou net zo goed een melding kunnen zijn; de plek om dat aan te
roepen is
MeldingService.StuurAsync. - Instellen per gebruiker. Wie geen meldingen wil, kan ze nu alleen op het toestel zelf uitzetten.