App-Store-Vorbereitung: App Check, Release-Signing, Datenschutz, Doku

Ziel fürs Erste: TestFlight + Play-Internal-Testing (kein öffentlicher
Store-Eintrag). Code-seitig vorbereitet, alle Konsolen-Schritte für
Chris in firebase-einrichtung.md (Schritt 9-11) dokumentiert:

- App Check Client-Integration (Debug-Provider), Functions erzwingen
  es noch nicht (zweistufiger Rollout, siehe Doku)
- iOS: ITSAppUsesNonExemptEncryption gesetzt
- Android: Release-Signing über key.properties vorbereitet (Upload-Key
  fehlt noch bewusst, Erzeugung ist Chris' Schritt)
- flutter_launcher_icons vorbereitet für künftiges echtes App-Icon
- Datenschutzerklärung entworfen (docs/legal/datenschutz.html)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
cschlaefke 2026-08-20 00:09:39 +02:00
parent d120c4fc60
commit 7d9754282f
10 changed files with 348 additions and 15 deletions

5
.gitignore vendored
View file

@ -43,3 +43,8 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
# Android Release-Signing (Upload-Key + Passwörter — niemals committen)
/android/key.properties
/android/*.jks
/android/*.keystore

View file

@ -1,3 +1,6 @@
import java.io.FileInputStream
import java.util.Properties
plugins {
id("com.android.application")
// START: FlutterFire Configuration
@ -8,6 +11,16 @@ plugins {
id("dev.flutter.flutter-gradle-plugin")
}
// Release-Signing: Werte kommen aus android/key.properties (nicht im Repo,
// siehe key.properties.example). Ohne die Datei wird weiterhin mit dem
// Debug-Key signiert, damit lokale Debug-Builds unverändert funktionieren.
val keystorePropertiesFile = rootProject.file("key.properties")
val keystoreProperties = Properties()
val hasReleaseSigning = keystorePropertiesFile.exists()
if (hasReleaseSigning) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
android {
namespace = "dev.leafittome.app"
compileSdk = flutter.compileSdkVersion
@ -33,11 +46,26 @@ android {
versionName = flutter.versionName
}
signingConfigs {
if (hasReleaseSigning) {
create("release") {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["storePassword"] as String
}
}
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")
// Nutzt den echten Upload-Key, sobald key.properties existiert;
// bis dahin Fallback auf den Debug-Key (siehe oben).
signingConfig = if (hasReleaseSigning) {
signingConfigs.getByName("release")
} else {
signingConfigs.getByName("debug")
}
}
}
}

View file

@ -0,0 +1,4 @@
storePassword=
keyPassword=
keyAlias=upload
storeFile=../upload-keystore.jks

View file

@ -182,9 +182,64 @@ Danach neu bauen (`flutter run`) und den Google-Button auf iPhone **und** Androi
> - Beim Aktivieren zeigt die Konsole den Hinweis „**SHA-1-Releasefingerabdruck angeben**". Der gilt für den *nativen* Google-Flow (`google_sign_in`-Paket) — unser Browser-Flow braucht ihn nicht. Die **Debug**-Fingerabdrücke (SHA-1 + SHA-256 aus `~/.android/debug.keystore`) sind trotzdem per CLI im Projekt hinterlegt (`firebase apps:android:sha:create …`), damit später nichts fehlt (z. B. App Check). Vor einem App-Store-/Play-Store-Release muss zusätzlich der Fingerabdruck des **Release**-Schlüssels hinterlegt werden — den gibt es aber noch nicht.
> - Die `GoogleService-Info.plist`/`google-services.json` müssen nicht neu heruntergeladen werden — der Flow läuft über den Auth-Handler im Web, nicht über das native Google-SDK.
## Schritt 9 und folgende (kommen mit den nächsten Blöcken)
## Schritt 9: App Check aktivieren
- **App Check** — optionale Härtung vor dem App-Store-Release: bestätigt per Play Integrity (Android) / App Attest (iOS), dass Anfragen aus der echten App kommen. Bis dahin ist die Log-Warnung „No AppCheckProvider installed" harmlos und kann ignoriert werden — die Zugriffskontrolle leisten Login + Security Rules.
**So funktioniert es:** App Check bestätigt der Firebase-Console, dass ein Function-Aufruf wirklich aus der echten App kommt (Play Integrity auf Android, App Attest auf iOS) — Schutz gegen missbrauchte API-Keys/Function-URLs von außerhalb der App. Der Client-Code ist bereits vorbereitet (`FirebaseAppCheck.instance.activate(...)` in `lib/main.dart`), läuft aber noch mit dem **Debug-Provider** und die Functions **erzwingen** App Check noch nicht — die Log-Warnung „No AppCheckProvider installed" ist bis dahin harmlos, Login + Security Rules schützen weiterhin.
Zwei getrennte Schritte, **nacheinander**, nicht gleichzeitig (sonst sperrt man sich versehentlich selbst aus den Functions aus):
1. **Provider registrieren (Firebase-Konsole → App Check):**
- Android-App auswählen → **Play Integrity** als Provider aktivieren (kein zusätzliches Setup in der Play Console nötig, die API ist automatisch verfügbar).
- iOS-App auswählen → **App Attest** als Provider aktivieren.
- Für Testgeräte im Debug-Modus: beim ersten Start gibt die App in der Konsole (Logcat bzw. Xcode-Log) ein Debug-Token aus — das unter *App Check → Apps → \[App\] → Debug-Token verwalten* eintragen, sonst schlagen Debug-Builds nach dem Enforcement fehl.
- **Metriken abwarten:** In der Console unter *App Check → APIs* prüfen, dass für die genutzten Functions „Verified requests" ankommen (kann nach einem frischen Build ein paar Minuten dauern).
2. **Erst wenn Schritt 1 bestätigt ist:** In `functions/src/index.ts` und `functions/src/household.ts` bei den `onCall(...)`-Funktionen (`identifyPlant`, `diagnosePlant`, `analyzeLocation`, `assessPlantFit`, `joinHousehold`, `leaveHousehold`, `removeMember`) die Option `enforceAppCheck: true` ergänzen und neu deployen. Danach lehnen die Functions Aufrufe ohne gültiges App-Check-Token ab.
Für einen echten Release-Build sollte `main.dart` auf die Produktiv-Provider umgestellt werden (`AndroidProvider.playIntegrity` / `AppleProvider.appAttest` statt der Debug-Provider) — bis dahin reicht der Debug-Provider für eigene Testgeräte.
## Schritt 10: TestFlight einrichten (iOS)
Ziel: die App auf eigenen/Familien-Geräten installierbar machen, **ohne** öffentlichen Store-Eintrag oder Apple-Review (interne Tester werden nicht geprüft).
1. **App Store Connect** (<https://appstoreconnect.apple.com>, mit dem aktiven Apple-Developer-Konto) → *Meine Apps* → „+" → **Neue App**:
- Plattform iOS, Name „LeafItToMe" (falls der Name schon vergeben ist, z. B. „LeafItToMe Pflanzenpflege" versuchen), Bundle-ID `dev.leafittome.app` auswählen (aus der Liste, die Xcode/das Developer-Portal bereits kennt), SKU frei wählbar (z. B. `leafittome-001`).
2. **App-Informationen → Datenschutzerklärung-URL:** die gehostete Datenschutzerklärung eintragen (Entwurf liegt in `docs/legal/datenschutz.html`, Hosting-Vorschlag s. u.).
3. **App-Datenschutz (Privacy-Fragebogen):** Apple fragt nach Datentypen. Antworten passend zu `docs/legal/datenschutz.html`:
- *Kontaktdaten* → E-Mail-Adresse: ja, verknüpft mit Nutzer, für App-Funktionalität (Konto).
- *Fotos oder Videos* → ja, verknüpft mit Nutzer, für App-Funktionalität (Pflanzen-/Standort-Erkennung).
- *Nutzerinhalte* (sonstige, z. B. Pflanzendaten) → ja, verknüpft mit Nutzer, für App-Funktionalität.
- Kein Tracking, keine Daten zu Werbezwecken, keine Analyse-/Diagnosedaten (kein Analytics/Crashlytics im Projekt).
4. **Build hochladen:** `flutter build ipa` (Release-Signing über Xcode „Automatically manage signing"), dann per Xcode Organizer oder Transporter-App hochladen.
5. **TestFlight → Interne Tests:** neue Testgruppe anlegen (z. B. „Haushalt"), Tester per Apple-ID-E-Mail hinzufügen — die genannten Personen müssen als *Nutzer* im App-Store-Connect-Team stehen (bis zu 100 interne Tester, kein Review nötig, Build ist nach ein paar Minuten Verarbeitungszeit verfügbar).
## Schritt 11: Play Internal Testing einrichten (Android)
Ziel: dieselbe „ohne öffentlichen Store-Eintrag"-Stufe für Android.
1. **Voraussetzung — Release-Signing:** `android/key.properties` lokal anlegen (Vorlage: `android/key.properties.example`) und den Upload-Key erzeugen:
```
keytool -genkey -v -keystore android/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
```
**Wichtig:** Diesen Befehl bewusst selbst ausführen (per `! keytool ...` in der Eingabezeile) und die erzeugte `.jks`-Datei **sofort sichern** (Passwort-Manager + Backup außerhalb des Repos) — ein verlorener Upload-Key bedeutet, dass die App auf Play nie wieder aktualisiert werden kann. Datei und `key.properties` sind absichtlich in `.gitignore`, landen also nicht im Git-Repo.
2. **Release-APK/AAB bauen:** `flutter build appbundle --release` (nutzt automatisch den Release-Key, sobald `key.properties` existiert).
3. **Play Console** (<https://play.google.com/console>) → **App erstellen**: Name „LeafItToMe", Paketname `dev.leafittome.app` (wird beim ersten AAB-Upload festgelegt).
4. **App-Inhalte** (Pflichtabschnitte, auch für den internen Test):
- *Datenschutzerklärung:* URL zu `docs/legal/datenschutz.html` eintragen.
- *Data-Safety-Formular:* analog zum Apple-Fragebogen aus Schritt 10 — Fotos, E-Mail/Kontodaten, Nutzerinhalte werden erhoben, sind mit dem Nutzerkonto verknüpft, dienen ausschließlich der App-Funktion, keine Weitergabe zu Werbezwecken, Datenverschlüsselung bei Übertragung: ja, Löschung auf Anfrage: ja.
- *Content-Rating-Fragebogen:* Kategorie „Utility/Produktivität", keine der abgefragten Inhalte (Gewalt, Nacktheit, Glücksspiel etc.) treffen zu → niedrigste Alterseinstufung.
- *Zielgruppe:* Erwachsene/allgemein, nicht speziell an Kinder gerichtet.
- *Anzeigen:* keine Werbung in der App.
5. **Interner Test-Track:** *Testen → Interner Test* → neue Version → AAB hochladen → Tester per Google-Konto-E-Mail oder Google-Gruppe hinzufügen → Link zur Teilnahme an die Tester schicken (kein Review, Verfügbarkeit meist innerhalb weniger Minuten).
## Hosting-Vorschlag: Datenschutzerklärung öffentlich erreichbar machen
`docs/legal/datenschutz.html` ist bewusst eine einzelne, eigenständige HTML-Datei ohne Build-Schritt — sie kann 1:1 ausgeliefert werden. Da die eigene Domain für die App noch aussteht, als Zwischenlösung der pragmatischste Weg über den bereits laufenden Hetzner-VPS (dort läuft schon nginx als Reverse-Proxy vor Forgejo, siehe `docs/git-forgejo.md`):
1. Datei auf den Server kopieren, z. B. nach `/var/www/leafittome-legal/datenschutz.html`.
2. Kleinen `server{}`-Block (oder `location`-Block auf einem bestehenden Host) in der nginx-Config ergänzen, der diesen Ordner statisch ausliefert — entweder unter einer neuen Subdomain (`legal.cshomelabs.work`) oder einem Pfad auf einer bestehenden Domain, je nachdem was ohne DNS-Änderung am schnellsten geht.
3. Die resultierende URL in App Store Connect (Schritt 10) und Play Console (Schritt 11) eintragen.
Sobald die endgültige `leafittome`-Domain steht, kann die Seite dorthin umziehen — die App-Store-/Play-Einträge müssten dann nur die URL aktualisieren.
## Begriffe kurz erklärt

View file

@ -30,9 +30,29 @@ Private Flutter-App (iOS+Android) zur Pflanzenpflege für Haushalt + Pflanzen-Si
## Offen / Nächstes
### 1. Backlog
### 1. App-Store-Vorbereitung (läuft, 2026-08-20 begonnen)
Button „KI-Zweitmeinung" bei unbefriedigendem PlantNet-Ergebnis; Push-Anzeige auch bei App im Vordergrund; App Check vor App-Store-Release (`firebase-einrichtung.md` Schritt 9); Englisch (`app_en.arb`); `firebase-functions`-Paket-Upgrade (Deploy-Warnung, mit Breaking Changes — bei Gelegenheit).
Ziel fürs Erste: **nur TestFlight + Play-Internal-Testing**, kein öffentlicher Store-Eintrag (mit Chris abgestimmt — spart Screenshots/Store-Texte/Altersfreigabe für später). Bundle-ID bleibt bewusst `dev.leafittome.app` (eigene Domain steht noch aus, ist aber kein Blocker für TestFlight/Internal-Testing).
**Code-seitig erledigt:**
- App Check Client-Integration (Debug-Provider, `lib/main.dart`) — Functions erzwingen es noch nicht, siehe `firebase-einrichtung.md` Schritt 9 für den zweiten Schritt (Provider in der Console registrieren, dann erst `enforceAppCheck: true`).
- iOS: `ITSAppUsesNonExemptEncryption = false` in `Info.plist` (vermeidet wiederkehrende Export-Compliance-Nachfrage bei jedem TestFlight-Upload).
- Android: Release-Signing vorbereitet (`android/app/build.gradle.kts` liest `key.properties`, Vorlage `android/key.properties.example`; Datei + `.jks` sind in `.gitignore`). **Der Upload-Key selbst existiert noch nicht** — Chris muss ihn per `keytool` erzeugen (Befehl in `firebase-einrichtung.md` Schritt 11) und sofort sichern.
- `flutter_launcher_icons` vorbereitet (`pubspec.yaml`), zeigt auf `assets/icon/icon.png` — Datei existiert noch nicht.
- Entwurf Datenschutzerklärung: `docs/legal/datenschutz.html` (Platzhalter `[Name]`/`[E-Mail-Adresse]`/`[Datum]` müssen noch von Chris ausgefüllt werden), Hosting-Vorschlag (Hetzner-VPS/nginx) in `firebase-einrichtung.md`.
- Neue Doku-Schritte in `firebase-einrichtung.md`: **Schritt 9** (App Check, konkretisiert), **Schritt 10** (TestFlight einrichten), **Schritt 11** (Play Internal Testing einrichten) — inkl. Textvorlagen für Apples App-Privacy-Fragebogen und Googles Data-Safety-Formular.
**Noch offen (Chris' Konsolen-Schritte, alle in `firebase-einrichtung.md` Schritt 911 dokumentiert):**
- App-Icon: 1024×1024-Design liefern → unter `assets/icon/icon.png` ablegen → `dart run flutter_launcher_icons`.
- Datenschutzerklärung: Platzhalter ausfüllen + irgendwo öffentlich hosten (Vorschlag: Hetzner-VPS).
- Android-Upload-Key erzeugen (`keytool`, Schritt 11) und sichern.
- App Check: Play Integrity/App Attest in der Firebase-Console registrieren, Metriken abwarten, danach `enforceAppCheck: true` in den Functions + Redeploy.
- App Store Connect: App-Eintrag anlegen, Privacy-URL + App-Privacy-Fragebogen ausfüllen, Build hochladen, interne TestFlight-Gruppe + Tester.
- Play Console: App anlegen, Datenschutz-URL + Data-Safety-Formular + Content-Rating ausfüllen, internen Test-Track + Tester.
### 2. Backlog
Button „KI-Zweitmeinung" bei unbefriedigendem PlantNet-Ergebnis; Push-Anzeige auch bei App im Vordergrund; Englisch (`app_en.arb`); `firebase-functions`-Paket-Upgrade (Deploy-Warnung, mit Breaking Changes — bei Gelegenheit).
## Stolperfallen (teuer erkauft, nicht erneut zahlen)

120
docs/legal/datenschutz.html Normal file
View file

@ -0,0 +1,120 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Datenschutzerklärung LeafItToMe</title>
<style>
:root { color-scheme: light dark; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
max-width: 40rem;
margin: 2.5rem auto;
padding: 0 1.25rem;
line-height: 1.55;
}
h1 { font-size: 1.5rem; }
h2 { font-size: 1.15rem; margin-top: 2rem; }
ul { padding-left: 1.25rem; }
.hint {
background: color-mix(in srgb, canvastext 6%, transparent);
border-radius: 0.5rem;
padding: 0.75rem 1rem;
font-size: 0.9rem;
}
</style>
</head>
<body>
<h1>Datenschutzerklärung LeafItToMe</h1>
<p><em>Stand: [Datum einsetzen]</em></p>
<p class="hint">
<strong>Hinweis für Chris (vor Veröffentlichung entfernen):</strong>
Platzhalter <code>[Name]</code>, <code>[E-Mail-Adresse]</code> und <code>[Datum]</code>
ausfüllen. Diese Seite ist als öffentlich erreichbare, eigenständige HTML-Datei gedacht
(Hosting-Vorschlag in <code>docs/firebase-einrichtung.md</code>), auf die im Apple/Google-
Account bei „Datenschutzerklärung" verlinkt wird.
</p>
<h2>Verantwortlicher</h2>
<p>
[Name]<br>
E-Mail: [E-Mail-Adresse]
</p>
<p>
LeafItToMe ist eine private, nicht kommerzielle App zur Pflanzenpflege für einen
Haushalt und die Personen, die dieser Haushalt zur Mitverwaltung oder als
Pflanzen-Sitter einlädt. Es werden keine Daten verkauft, keine Werbung
eingeblendet und keine Nutzungsdaten zu Analyse- oder Marketingzwecken erhoben.
</p>
<h2>Welche Daten werden verarbeitet?</h2>
<ul>
<li><strong>Konto:</strong> E-Mail-Adresse (bei Registrierung mit E-Mail/Passwort)
oder die von Apple/Google beim Login übermittelten Basisdaten
(Name, E-Mail-Adresse, Konto-ID).</li>
<li><strong>Haushalts- und Pflanzendaten:</strong> Haushaltsname, Mitglieder samt
Rolle (Mitglied/Sitter), angelegte Pflanzen mit Name, Art, Pflegeplan sowie
Gieß-/Dünge-/Umtopf-Historie.</li>
<li><strong>Fotos:</strong> Fotos, die du von Pflanzen oder Stellplätzen aufnimmst
oder aus der Galerie auswählst, um eine Pflanze zu erkennen, ihren
Gesundheitszustand einzuschätzen oder die Lichtverhältnisse eines Stellplatzes
zu bewerten.</li>
<li><strong>Push-Benachrichtigungen:</strong> ein technisches Geräte-Token, um dir
tägliche Erinnerungen zuzustellen, sowie die von dir eingestellte Uhrzeit und
Zeitzone.</li>
</ul>
<h2>Wofür werden die Daten verwendet?</h2>
<p>
Ausschließlich für die Kernfunktion der App: Pflanzen anzulegen und zu
identifizieren, Pflegepläne zu erstellen, Erinnerungen zu verschicken sowie
Krankheits- und Standort-Analysen auf Anfrage durchzuführen. Für die Foto-Analyse
werden die von dir aufgenommenen Bilder an folgende externe Dienste übermittelt:
</p>
<ul>
<li><strong>PlantNet</strong> (Pl@ntNet, Frankreich) zur automatischen
Pflanzenart-Erkennung.</li>
<li><strong>Anthropic</strong> (Anthropic PBC, USA) zur Erstellung von
Pflegetexten sowie für die (auf Anfrage ausgelösten) Krankheits- und
Stellplatz-Analysen.</li>
</ul>
<p>
Diese Übermittlung erfolgt nur für die jeweilige Anfrage, nicht dauerhaft und
nicht zu Werbezwecken.
</p>
<h2>Wo werden die Daten gespeichert?</h2>
<p>
Alle App-Daten (Konten, Haushalte, Pflanzen, Fotos) liegen bei
<strong>Google Firebase</strong>, Rechenzentrumsregion <code>europe-west3</code>
(Frankfurt, Deutschland). Google LLC/Google Ireland Limited verarbeitet diese
Daten als Auftragsverarbeiter.
</p>
<h2>Weitergabe an Dritte</h2>
<p>
Eine Weitergabe erfolgt nur an die oben genannten Dienste (Firebase, PlantNet,
Anthropic) im Rahmen der Auftragsverarbeitung, sowie an die Mitglieder und
Sitter deines eigenen Haushalts, die naturgemäß dieselben Haushaltsdaten sehen.
Ein Verkauf von Daten findet nicht statt.
</p>
<h2>Speicherdauer und Löschung</h2>
<p>
Daten werden gespeichert, solange dein Konto bzw. der Haushalt besteht.
Zur Löschung deines Kontos oder einzelner Daten wende dich an
[E-Mail-Adresse].
</p>
<h2>Deine Rechte</h2>
<p>
Du hast das Recht auf Auskunft, Berichtigung, Löschung, Einschränkung der
Verarbeitung, Datenübertragbarkeit und Widerspruch gemäß Art. 1521 DSGVO
sowie ein Beschwerderecht bei einer Datenschutzaufsichtsbehörde. Wende dich
dazu an [E-Mail-Adresse].
</p>
</body>
</html>

View file

@ -24,6 +24,8 @@
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>CFBundleURLTypes</key>
<array>
<dict>

View file

@ -1,3 +1,4 @@
import 'package:firebase_app_check/firebase_app_check.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -12,6 +13,13 @@ Future<void> main() async {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
// Debug-Provider, bis Play Integrity (Android) / App Attest (iOS) in der
// Firebase-Console registriert sind (docs/firebase-einrichtung.md Schritt 9).
// Die Functions erzwingen App Check noch nicht reines Vorbereiten.
await FirebaseAppCheck.instance.activate(
providerAndroid: AndroidDebugProvider(),
providerApple: AppleDebugProvider(),
);
final prefs = await SharedPreferences.getInstance();
runApp(
ProviderScope(

View file

@ -13,10 +13,10 @@ packages:
dependency: transitive
description:
name: _flutterfire_internals
sha256: "460e9e684edb461d85498fc166ff8416f303f22216838d302d80676b348c6a4c"
sha256: "6727cf2ced9b104abca9daa278380be2eca2b98ce33d4b46f11708e387dc6b4d"
url: "https://pub.dev"
source: hosted
version: "1.3.75"
version: "1.3.76"
analyzer:
dependency: transitive
description:
@ -33,6 +33,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.13.2"
archive:
dependency: transitive
description:
name: archive
sha256: be169cf6ac481e052c4538715d88841d567150dfe1df38aaec76461a4e7b39f2
url: "https://pub.dev"
source: hosted
version: "4.1.0"
args:
dependency: transitive
description:
@ -73,6 +81,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.4.1"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f"
url: "https://pub.dev"
source: hosted
version: "2.0.4"
cli_config:
dependency: transitive
description:
@ -81,6 +97,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.2.0"
cli_util:
dependency: transitive
description:
name: cli_util
sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c
url: "https://pub.dev"
source: hosted
version: "0.4.2"
clock:
dependency: transitive
description:
@ -273,6 +297,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.9.3+5"
firebase_app_check:
dependency: "direct main"
description:
name: firebase_app_check
sha256: d422642d973b0c636e0582127a47319d8ac9140195e7330c71965d3b6b263095
url: "https://pub.dev"
source: hosted
version: "0.4.6"
firebase_app_check_platform_interface:
dependency: transitive
description:
name: firebase_app_check_platform_interface
sha256: "645ff25c18160a2c6e6b487d3466b247619e0bf09e2b1f641d476b2a72f92106"
url: "https://pub.dev"
source: hosted
version: "0.4.2"
firebase_app_check_web:
dependency: transitive
description:
name: firebase_app_check_web
sha256: "66c938d522c8c325515d222aa55560921b063d06791cf95aa7c405183a3a454f"
url: "https://pub.dev"
source: hosted
version: "0.2.6"
firebase_auth:
dependency: "direct main"
description:
@ -309,26 +357,26 @@ packages:
dependency: "direct main"
description:
name: firebase_core
sha256: "6f22d1c62e0c20976f02cd842c7b7cd3c0f561cc2052586411871045c08860c9"
sha256: "9478ca6700c02d315c6aba37e206e612317f98bb4f335bb1cbd6e0ce67dcf764"
url: "https://pub.dev"
source: hosted
version: "4.12.1"
version: "4.13.0"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
sha256: f74d1d6fabccf7743b0144c2ed363d81049e258e22428ebb6fb0faec2fa7d938
sha256: e28f9afdcb5b0f0a8ea74ea3b322f5a7592c81cb45dd9d189913bdae08a2089a
url: "https://pub.dev"
source: hosted
version: "8.0.0"
version: "8.1.0"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
sha256: ddab99d709b8c27dd47576eb05a1e719e07a2aa45c009a49ae92ac4d2a8ca555
sha256: f471a288b0101a45567548322ac4a5ad31e3ecbf87a576dcc0e424e6a11e04ea
url: "https://pub.dev"
source: hosted
version: "3.9.1"
version: "3.10.0"
firebase_messaging:
dependency: "direct main"
description:
@ -390,6 +438,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_launcher_icons:
dependency: "direct dev"
description:
name: flutter_launcher_icons
sha256: "10f13781741a2e3972126fae08393d3c4e01fa4cd7473326b94b72cf594195e7"
url: "https://pub.dev"
source: hosted
version: "0.14.4"
flutter_lints:
dependency: "direct dev"
description:
@ -485,6 +541,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.1.2"
image:
dependency: transitive
description:
name: image
sha256: "1976370a4df3091bb0f72409c187ad1f9132a818bc6b95ca59c0bae1c75c688e"
url: "https://pub.dev"
source: hosted
version: "4.9.2"
image_picker:
dependency: "direct main"
description:
@ -565,6 +629,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.5"
json_annotation:
dependency: transitive
description:
name: json_annotation
sha256: "2a743920d81b7910627f68ee2c9ac1fc0bfee32b9fc3403587d7c6791ca12f80"
url: "https://pub.dev"
source: hosted
version: "4.12.0"
leak_tracker:
dependency: transitive
description:
@ -741,6 +813,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.5.2"
posix:
dependency: transitive
description:
name: posix
sha256: bc1bad54ad2b735816e31f8d4600cfde6c7839975085ddfbca48b6c9f7c4044e
url: "https://pub.dev"
source: hosted
version: "6.5.2"
pub_semver:
dependency: transitive
description:

View file

@ -48,6 +48,7 @@ dependencies:
firebase_storage: ^13.4.5
firebase_messaging: ^16.4.3
flutter_timezone: ^5.1.0
firebase_app_check: ^0.4.6
dev_dependencies:
flutter_test:
@ -61,6 +62,7 @@ dev_dependencies:
flutter_lints: ^6.0.0
fake_cloud_firestore: ^4.2.0
firebase_auth_mocks: ^0.15.2
flutter_launcher_icons: ^0.14.4
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
@ -104,3 +106,12 @@ flutter:
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/to/font-from-package
# Icon-Generierung (flutter_launcher_icons): Sobald ein echtes 1024x1024-Design
# unter assets/icon/icon.png liegt, generiert `dart run flutter_launcher_icons`
# daraus alle iOS-/Android-Icon-Größen. Bis dahin bleibt das Flutter-Standardlogo.
flutter_launcher_icons:
image_path: "assets/icon/icon.png"
android: true
ios: true
remove_alpha_ios: true