Firebase angebunden: Projekt leaf-it-to-me-app, App-Registrierung iOS/Android, Initialisierung beim Start

- flutterfire configure: firebase_options.dart, google-services.json, GoogleService-Info.plist
- firebase_core eingebunden, Firebase.initializeApp in main.dart
- Doku firebase-einrichtung.md auf aktuellen Stand gebracht
- Verifiziert: flutter analyze/test grün, Android-Debug-Build erfolgreich

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
cschlaefke 2026-07-18 22:44:24 +02:00
parent a5b79193dd
commit 4390949c7e
11 changed files with 176 additions and 1 deletions

View file

@ -1,5 +1,8 @@
plugins {
id("com.android.application")
// START: FlutterFire Configuration
id("com.google.gms.google-services")
// END: FlutterFire Configuration
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")

View file

@ -0,0 +1,29 @@
{
"project_info": {
"project_number": "724282636354",
"project_id": "leaf-it-to-me-app",
"storage_bucket": "leaf-it-to-me-app.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:724282636354:android:db0671eaf1218c414195db",
"android_client_info": {
"package_name": "dev.leafittome.app"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyBl591_B4-LJ2k_D-kSBJx_PILYOevnkHg"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}

View file

@ -20,6 +20,9 @@ pluginManagement {
plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "8.11.1" apply false
// START: FlutterFire Configuration
id("com.google.gms.google-services") version("4.3.15") apply false
// END: FlutterFire Configuration
id("org.jetbrains.kotlin.android") version "2.2.20" apply false
}

View file

@ -2,7 +2,7 @@
Firebase ist Googles „Backend als Dienst": Es liefert uns Login (**Auth**), Datenbank mit Echtzeit-Sync (**Firestore**), Foto-Speicher (**Storage**), serverseitigen Code (**Cloud Functions**) und Push-Nachrichten (**FCM**) — ohne dass wir einen eigenen Server betreiben.
> **Stand:** Vorbereitung. Die App läuft aktuell noch mit Demo-Daten ohne Firebase. Dieses Dokument wird mit jedem Firebase-Baustein erweitert und führt dich durch alles, was du selbst (mit deinem Google-Konto) tun musst.
> **Stand:** Schritt 13 sind erledigt (18.07.2026): Projekt `leaf-it-to-me-app` existiert, die iOS- und Android-App sind registriert, `lib/firebase_options.dart` ist erzeugt und Firebase wird beim App-Start initialisiert. Die App-Daten (Pflanzen etc.) laufen noch über Demo-Daten — Firestore folgt im nächsten Block. Dieses Dokument wird mit jedem Baustein erweitert.
## Was wofür? (Überblick)
@ -52,6 +52,13 @@ flutterfire configure
`flutterfire configure` erzeugt `lib/firebase_options.dart` — darin stehen die Projekt-Kennungen (keine Geheimnisse, darf ins Git). Die eigentlichen API-Keys (Anthropic, PlantNet) leben **nur** in der Cloud-Functions-Umgebung, niemals in der App.
**Was dabei konkret passiert ist (zum Nachvollziehen):**
- In der Firebase Console tauchen unter *Projekteinstellungen → Meine Apps* jetzt zwei Apps auf (iOS und Android, jeweils `dev.leafittome.app`).
- `android/app/google-services.json` und `ios/Runner/GoogleService-Info.plist` sind die plattformspezifischen Verbindungsdateien; `firebase.json` merkt sich die Zuordnung fürs CLI.
- In den Android-Gradle-Dateien wurde das `google-services`-Plugin eingetragen (verarbeitet die JSON-Datei beim Build).
- `lib/main.dart` ruft beim Start `Firebase.initializeApp(...)` auf — ab jetzt können wir nach und nach Auth, Firestore, Storage und FCM andocken.
## Schritt 4 und folgende (kommen mit den nächsten Blöcken)
- **Firestore-Datenmodell + Sicherheitsregeln** — wer darf was lesen/schreiben (Haushalts-Mitgliedschaft), Doku folgt beim Firestore-Block.

1
firebase.json Normal file
View file

@ -0,0 +1 @@
{"flutter":{"platforms":{"android":{"default":{"projectId":"leaf-it-to-me-app","appId":"1:724282636354:android:db0671eaf1218c414195db","fileOutput":"android/app/google-services.json"}},"ios":{"default":{"projectId":"leaf-it-to-me-app","appId":"1:724282636354:ios:7c2855f20b2ba5ba4195db","uploadDebugSymbols":false,"fileOutput":"ios/Runner/GoogleService-Info.plist"}},"dart":{"lib/firebase_options.dart":{"projectId":"leaf-it-to-me-app","configurations":{"android":"1:724282636354:android:db0671eaf1218c414195db","ios":"1:724282636354:ios:7c2855f20b2ba5ba4195db"}}}}}}

View file

@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
1AE0D843A80013A3DE955CB5 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5A01F7941722D9D24C51BCF1 /* GoogleService-Info.plist */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
@ -45,6 +46,7 @@
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
5A01F7941722D9D24C51BCF1 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
@ -94,6 +96,7 @@
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
5A01F7941722D9D24C51BCF1 /* GoogleService-Info.plist */,
);
sourceTree = "<group>";
};
@ -216,6 +219,7 @@
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
1AE0D843A80013A3DE955CB5 /* GoogleService-Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>API_KEY</key>
<string>AIzaSyBpDElvx9ahyDnBerwL9iQrbuebDtCHRFA</string>
<key>GCM_SENDER_ID</key>
<string>724282636354</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>dev.leafittome.app</string>
<key>PROJECT_ID</key>
<string>leaf-it-to-me-app</string>
<key>STORAGE_BUCKET</key>
<string>leaf-it-to-me-app.firebasestorage.app</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:724282636354:ios:7c2855f20b2ba5ba4195db</string>
</dict>
</plist>

68
lib/firebase_options.dart Normal file
View file

@ -0,0 +1,68 @@
// File generated by FlutterFire CLI.
// ignore_for_file: type=lint
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for web - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for macos - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.windows:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for windows - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyBl591_B4-LJ2k_D-kSBJx_PILYOevnkHg',
appId: '1:724282636354:android:db0671eaf1218c414195db',
messagingSenderId: '724282636354',
projectId: 'leaf-it-to-me-app',
storageBucket: 'leaf-it-to-me-app.firebasestorage.app',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyBpDElvx9ahyDnBerwL9iQrbuebDtCHRFA',
appId: '1:724282636354:ios:7c2855f20b2ba5ba4195db',
messagingSenderId: '724282636354',
projectId: 'leaf-it-to-me-app',
storageBucket: 'leaf-it-to-me-app.firebasestorage.app',
iosBundleId: 'dev.leafittome.app',
);
}

View file

@ -1,12 +1,17 @@
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'app.dart';
import 'core/settings/settings_provider.dart';
import 'firebase_options.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
final prefs = await SharedPreferences.getInstance();
runApp(
ProviderScope(

View file

@ -129,6 +129,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "7.0.1"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
sha256: "6f22d1c62e0c20976f02cd842c7b7cd3c0f561cc2052586411871045c08860c9"
url: "https://pub.dev"
source: hosted
version: "4.12.1"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
sha256: f74d1d6fabccf7743b0144c2ed363d81049e258e22428ebb6fb0faec2fa7d938
url: "https://pub.dev"
source: hosted
version: "8.0.0"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
sha256: ddab99d709b8c27dd47576eb05a1e719e07a2aa45c009a49ae92ac4d2a8ca555
url: "https://pub.dev"
source: hosted
version: "3.9.1"
fixnum:
dependency: transitive
description:

View file

@ -40,6 +40,7 @@ dependencies:
go_router: ^17.3.0
shared_preferences: ^2.5.5
intl: any
firebase_core: ^4.12.1
dev_dependencies:
flutter_test: