Eerste commit
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user