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:
parent
d120c4fc60
commit
7d9754282f
10 changed files with 348 additions and 15 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
4
android/key.properties.example
Normal file
4
android/key.properties.example
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
storePassword=
|
||||
keyPassword=
|
||||
keyAlias=upload
|
||||
storeFile=../upload-keystore.jks
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 9–11 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
120
docs/legal/datenschutz.html
Normal 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. 15–21 DSGVO
|
||||
sowie ein Beschwerderecht bei einer Datenschutzaufsichtsbehörde. Wende dich
|
||||
dazu an [E-Mail-Adresse].
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -24,6 +24,8 @@
|
|||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
96
pubspec.lock
96
pubspec.lock
|
|
@ -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:
|
||||
|
|
|
|||
11
pubspec.yaml
11
pubspec.yaml
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue