149 lines
7.4 KiB
Markdown
149 lines
7.4 KiB
Markdown
# 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
|
|
|
|
1. Ga naar console.firebase.google.com en maak een project, bijvoorbeeld **MijnBesluit**.
|
|
Google Analytics kun je overslaan.
|
|
2. Voeg een **Android-app** toe met pakketnaam `nl.mijnbesluit.app` - precies zoals hij in
|
|
`MijnBesluit.App.csproj` bij `ApplicationId` staat.
|
|
3. Download `google-services.json` en zet hem in `src\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
|
|
|
|
1. In Firebase: **Projectinstellingen > Serviceaccounts > Nieuwe persoonlijke sleutel genereren**.
|
|
Er wordt een json-bestand gedownload.
|
|
2. Zet dat op de server als `C:\MijnBesluitData\keys\firebase.json`.
|
|
3. Zet in `C:\MijnBesluitData\appsettings.secrets.json`:
|
|
|
|
```json
|
|
"Push": {
|
|
"ServiceAccountFile": "C:\\MijnBesluitData\\keys\\firebase.json"
|
|
}
|
|
```
|
|
|
|
4. `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
|
|
|
|
1. App opnieuw installeren en inloggen. Android vraagt nu toestemming voor meldingen - die
|
|
vraag komt van `Permissions.PostNotifications`, verplicht sinds Android 13.
|
|
2. **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 ontbreekt
|
|
`google-services.json` in de APK die op het toestel staat (is hij ná het bouwen toegevoegd,
|
|
bouw dan opnieuw), of heeft de gebruiker de toestemmingsvraag weggeklikt.
|
|
|
|
```sql
|
|
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 `Meldingsdienst` in `Platforms\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 het `notification`-deel voor Android zelf, en
|
|
in het `data`-deel voor de app. Zie `FirebasePush.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.
|