├── functions ├── .gitignore ├── index.js └── package.json ├── ios ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── Runner.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ └── project.pbxproj ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── WorkspaceSettings.xcsettings │ │ └── IDEWorkspaceChecks.plist ├── RunnerTests │ └── RunnerTests.swift └── .gitignore ├── res ├── github.png ├── medium.png ├── quickcoder.png └── firebase_compendium_logo.png ├── web ├── favicon.png ├── icons │ ├── Icon-192.png │ ├── Icon-512.png │ ├── Icon-maskable-192.png │ └── Icon-maskable-512.png ├── cors.json ├── manifest.json └── index.html ├── .firebase ├── hosting.cHVibGlj.cache ├── hosting.d2Vi.cache └── hosting.YnVpbGRcd2Vi.cache ├── android ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── drawable │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable-v21 │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── values │ │ │ │ │ └── styles.xml │ │ │ │ └── values-night │ │ │ │ │ └── styles.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── flutter_firebase │ │ │ │ │ └── MainActivity.kt │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ └── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore ├── build.gradle └── settings.gradle ├── .metadata ├── lib ├── firebase │ ├── functions.dart │ ├── storage.dart │ ├── auth.dart │ └── firestore.dart ├── pages │ ├── remote_config_page.dart │ ├── crashlytics_page.dart │ ├── functions_page.dart │ ├── firestore_page.dart │ ├── storage_page.dart │ └── auth_page.dart ├── widgets │ └── file_widget.dart └── main.dart ├── firebase.json ├── pubspec.yaml ├── .gitignore ├── LICENSE ├── analysis_options.yaml ├── README.md └── pubspec.lock /functions/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /res/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/res/github.png -------------------------------------------------------------------------------- /res/medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/res/medium.png -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/web/favicon.png -------------------------------------------------------------------------------- /res/quickcoder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/res/quickcoder.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/web/icons/Icon-512.png -------------------------------------------------------------------------------- /res/firebase_compendium_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/res/firebase_compendium_logo.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /.firebase/hosting.cHVibGlj.cache: -------------------------------------------------------------------------------- 1 | index.html,1664826907731,07c3be46501878c085620a1f38dd15d257b664dfe1551b324bc48fb612b0a637 2 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xeladu/flutter_firebase/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /web/cors.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "origin": [ 4 | "*" 5 | ], 6 | "method": [ 7 | "GET" 8 | ], 9 | "maxAgeSeconds": 3600 10 | } 11 | ] -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/flutter_firebase/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.flutter_firebase 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() 6 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip 6 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/to/reference-keystore 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /functions/index.js: -------------------------------------------------------------------------------- 1 | const { onCall, onRequest } = require("firebase-functions/v2/https"); 2 | 3 | exports.toUpperCase = onCall((request) => { 4 | return request.data.toUpperCase(); 5 | }); 6 | 7 | exports.toLowerCase = onRequest((request, result) => { 8 | result.status(200).send(request.body.toString().toLowerCase()); 9 | }); -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 5f105a6ca7a5ac7b8bc9b241f4c2d86f4188cf5c 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /lib/firebase/functions.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_functions/cloud_functions.dart'; 2 | 3 | class Functions { 4 | static Future> call( 5 | String functionName, dynamic arguments) async { 6 | return await FirebaseFunctions.instance 7 | .httpsCallable(functionName) 8 | .call(arguments); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ios/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | rootProject.buildDir = "../build" 9 | subprojects { 10 | project.buildDir = "${rootProject.buildDir}/${project.name}" 11 | } 12 | subprojects { 13 | project.evaluationDependsOn(":app") 14 | } 15 | 16 | tasks.register("clean", Delete) { 17 | delete rootProject.buildDir 18 | } 19 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "functions": { 3 | "source": "functions" 4 | }, 5 | "hosting": { 6 | "public": "build/web", 7 | "ignore": [ 8 | "firebase.json", 9 | "**/.*", 10 | "**/node_modules/**" 11 | ], 12 | "rewrites": [ 13 | { 14 | "source": "**", 15 | "destination": "/index.html" 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | 4 | @main 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /functions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions", 3 | "description": "Cloud Functions for Firebase", 4 | "scripts": { 5 | "serve": "firebase emulators:start --only functions", 6 | "shell": "firebase functions:shell", 7 | "start": "npm run shell", 8 | "deploy": "firebase deploy --only functions", 9 | "logs": "firebase functions:log" 10 | }, 11 | "engines": { 12 | "node": "16" 13 | }, 14 | "main": "index.js", 15 | "dependencies": { 16 | "firebase-admin": "^10.0.2", 17 | "firebase-functions": "^3.18.0" 18 | }, 19 | "devDependencies": { 20 | "firebase-functions-test": "^0.2.0" 21 | }, 22 | "private": true 23 | } 24 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /.firebase/hosting.d2Vi.cache: -------------------------------------------------------------------------------- 1 | cors.json,1655811477171,ad45ca0264c9c9e392669e135b28b6c11585424f346c9813a57e53c00e147bbd 2 | favicon.png,1633551548067,0cab6e3dd5a9f008afdd133e1e1207cf65f2f2a10eb6712e3c209d8a5f76425a 3 | index.html,1653129654713,f8aa29aaa052d24e7c50fe921fa53aa5c77056129405106131ab8b0aeabe8082 4 | manifest.json,1653129654720,e3caad1c9bf25d751519a9a6eb9149cf4c17930377147c770fd755192ac071f8 5 | icons/Icon-192.png,1633551548068,eaf2464bfb1d192fdd192a616f7b858dee456d573c6ec619648a1dcf2bdddfa6 6 | icons/Icon-maskable-192.png,1633551618484,196ce9142a3442ab37ae90cd46c3389e4660400c859b81cbb0538a51b39752eb 7 | icons/Icon-512.png,1633551548069,9cf4cd298ae95acc1f25e97d88aa3f6bbfdf40867ea0f8a854c4393f49d56e64 8 | icons/Icon-maskable-512.png,1633551618480,6833b7c449e0dd24d5e164a53cc4557e643893e675b476b05efcbb9a6aa05bf0 9 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | }() 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | plugins { 20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 21 | id "com.android.application" version "7.3.0" apply false 22 | id "org.jetbrains.kotlin.android" version "1.7.10" apply false 23 | } 24 | 25 | include ":app" 26 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_firebase 2 | description: A Flutter demo app to interact with various Firebase services 3 | publish_to: 'none' 4 | version: 1.0.0+1 5 | 6 | environment: 7 | sdk: ">=3.5.0 <4.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | 13 | cupertino_icons: ^1.0.2 14 | cloud_firestore: ^5.4.0 15 | cloud_functions: ^5.1.0 16 | dio: ^5.4.0 17 | firebase_analytics: ^11.3.0 18 | firebase_app_check: ^0.3.1 19 | firebase_auth: ^5.2.0 20 | firebase_core: ^3.4.0 21 | firebase_remote_config: ^5.1.0 22 | firebase_storage: ^12.2.0 23 | image_picker: ^1.0.7 24 | intl: ^0.19.0 25 | url_launcher: ^6.1.2 26 | firebase_crashlytics: ^4.1.0 27 | 28 | dev_dependencies: 29 | flutter_test: 30 | sdk: flutter 31 | 32 | flutter_lints: ^3.0.1 33 | 34 | flutter: 35 | uses-material-design: true 36 | 37 | assets: 38 | - res/firebase_compendium_logo.png 39 | - res/github.png 40 | - res/medium.png 41 | - res/quickcoder.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | 36 | # Symbolication related 37 | app.*.symbols 38 | 39 | # Obfuscation related 40 | app.*.map.json 41 | 42 | # Android Studio will place build artifacts here 43 | /android/app/debug 44 | /android/app/profile 45 | /android/app/release 46 | lib/firebase_options.dart 47 | .firebaserc 48 | android/app/google-services.json 49 | ios/firebase_app_id_file.json 50 | ios/Runner/GoogleService-Info.plist 51 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flutter_firebase", 3 | "short_name": "flutter_firebase", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /lib/pages/remote_config_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_remote_config/firebase_remote_config.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class RemoteConfigPage extends StatefulWidget { 5 | const RemoteConfigPage({super.key}); 6 | 7 | @override 8 | State createState() => _State(); 9 | } 10 | 11 | class _State extends State { 12 | String platformString = "Hello!"; 13 | 14 | @override 15 | void initState() { 16 | super.initState(); 17 | 18 | FirebaseRemoteConfig.instance.fetchAndActivate().then((_) { 19 | platformString = 20 | FirebaseRemoteConfig.instance.getString("platformString"); 21 | setState(() {}); 22 | }); 23 | } 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return Scaffold( 28 | appBar: 29 | AppBar(title: const Center(child: Text("Firebase Remote Config"))), 30 | body: Padding( 31 | padding: const EdgeInsets.all(10.0), 32 | child: Center( 33 | child: Text(platformString, 34 | style: const TextStyle( 35 | fontSize: 28, fontWeight: FontWeight.bold))))); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /lib/firebase/storage.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:typed_data'; 3 | 4 | import 'package:firebase_storage/firebase_storage.dart'; 5 | 6 | class Storage { 7 | static Future> getData() async { 8 | final ref = FirebaseStorage.instance.ref(); 9 | 10 | var files = await ref.list(const ListOptions(maxResults: 5)); 11 | var res = []; 12 | 13 | for (var item in files.items) { 14 | var content = await item.getData(); 15 | var created = (await item.getMetadata()).timeCreated!; 16 | 17 | res.add(FileData(content!, item.name, created, item)); 18 | } 19 | 20 | return res; 21 | } 22 | 23 | static Future deleteItem(Reference ref) async { 24 | await ref.delete(); 25 | } 26 | 27 | static UploadTask uploadItem(File file, String targetName) { 28 | final ref = FirebaseStorage.instance.ref(); 29 | 30 | var child = ref.child(targetName); 31 | 32 | // With the UploadTask object you can listen to progress changes and control 33 | // the upload 34 | return child.putFile(file); 35 | } 36 | } 37 | 38 | class FileData { 39 | final Uint8List content; 40 | final String name; 41 | final DateTime uploadDate; 42 | final Reference reference; 43 | 44 | FileData(this.content, this.name, this.uploadDate, this.reference); 45 | } 46 | -------------------------------------------------------------------------------- /lib/firebase/auth.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_auth/firebase_auth.dart'; 2 | 3 | class Auth { 4 | static Future mailRegister(String mail, String pwd) async { 5 | try { 6 | await FirebaseAuth.instance 7 | .createUserWithEmailAndPassword(email: mail, password: pwd); 8 | return null; 9 | } on FirebaseAuthException catch (ex) { 10 | return "${ex.code}: ${ex.message}"; 11 | } 12 | } 13 | 14 | static Future signOut() async { 15 | try { 16 | await FirebaseAuth.instance.signOut(); 17 | return null; 18 | } on FirebaseAuthException catch (ex) { 19 | return "${ex.code}: ${ex.message}"; 20 | } 21 | } 22 | 23 | static Future mailSignIn(String mail, String pwd) async { 24 | try { 25 | await FirebaseAuth.instance 26 | .signInWithEmailAndPassword(email: mail, password: pwd); 27 | return null; 28 | } on FirebaseAuthException catch (ex) { 29 | return "${ex.code}: ${ex.message}"; 30 | } 31 | } 32 | 33 | static Future googleSignIn() async { 34 | try { 35 | await FirebaseAuth.instance.signInWithPopup(GoogleAuthProvider()); 36 | return null; 37 | } on FirebaseAuthException catch (ex) { 38 | return "${ex.code}: ${ex.message}"; 39 | } on UnimplementedError catch (ex) { 40 | return ex.message; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | flutter_firebase 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | id "kotlin-android" 4 | // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. 5 | id "dev.flutter.flutter-gradle-plugin" 6 | } 7 | 8 | android { 9 | namespace = "com.example.flutter_firebase" 10 | compileSdk = flutter.compileSdkVersion 11 | ndkVersion = flutter.ndkVersion 12 | 13 | compileOptions { 14 | sourceCompatibility = JavaVersion.VERSION_1_8 15 | targetCompatibility = JavaVersion.VERSION_1_8 16 | } 17 | 18 | kotlinOptions { 19 | jvmTarget = JavaVersion.VERSION_1_8 20 | } 21 | 22 | defaultConfig { 23 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 24 | applicationId = "com.example.flutter_firebase" 25 | // You can update the following values to match your application needs. 26 | // For more information, see: https://flutter.dev/to/review-gradle-config. 27 | minSdk = 23 28 | targetSdk = flutter.targetSdkVersion 29 | versionCode = flutter.versionCode 30 | versionName = flutter.versionName 31 | } 32 | 33 | buildTypes { 34 | release { 35 | // TODO: Add your own signing config for the release build. 36 | // Signing with the debug keys for now, so `flutter run --release` works. 37 | signingConfig = signingConfigs.debug 38 | } 39 | } 40 | } 41 | 42 | flutter { 43 | source = "../.." 44 | } 45 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Flutter Firebase 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | flutter_firebase 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | CADisableMinimumFrameDurationOnPhone 45 | 46 | UIApplicationSupportsIndirectInputEvents 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /lib/widgets/file_widget.dart: -------------------------------------------------------------------------------- 1 | import 'dart:typed_data'; 2 | import 'package:intl/intl.dart'; 3 | import 'package:flutter/material.dart'; 4 | 5 | class FileWidget extends StatelessWidget { 6 | final Uint8List content; 7 | final String fileName; 8 | final DateTime uploadDate; 9 | final Function() deleteFunction; 10 | 11 | const FileWidget( 12 | {super.key, 13 | required this.content, 14 | required this.fileName, 15 | required this.uploadDate, 16 | required this.deleteFunction}); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return Card( 21 | color: Colors.grey.shade300, 22 | child: Padding( 23 | padding: const EdgeInsets.all(10.0), 24 | child: Row(children: [ 25 | Image.memory( 26 | content, 27 | height: 60, 28 | width: 100, 29 | fit: BoxFit.contain, 30 | ), 31 | Container(width: 10), 32 | Expanded( 33 | child: Column( 34 | crossAxisAlignment: CrossAxisAlignment.start, 35 | children: [ 36 | Text( 37 | fileName, 38 | overflow: TextOverflow.ellipsis, 39 | style: const TextStyle(fontWeight: FontWeight.bold), 40 | ), 41 | Container(height: 5), 42 | Text(DateFormat("dd.MM.yyyy HH:mm").format(uploadDate), 43 | overflow: TextOverflow.ellipsis, 44 | style: const TextStyle(fontWeight: FontWeight.w500)) 45 | ], 46 | )), 47 | Container(width: 10), 48 | IconButton( 49 | onPressed: () async => await deleteFunction(), 50 | icon: const Icon( 51 | Icons.delete, 52 | color: Colors.redAccent, 53 | )) 54 | ]), 55 | )); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /lib/pages/crashlytics_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_crashlytics/firebase_crashlytics.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class CrashlyticsPage extends StatefulWidget { 5 | const CrashlyticsPage({super.key}); 6 | 7 | @override 8 | State createState() => _State(); 9 | } 10 | 11 | class _State extends State { 12 | @override 13 | Widget build(BuildContext context) { 14 | return Scaffold( 15 | appBar: 16 | AppBar(title: const Center(child: Text("Firebase Crashlytics"))), 17 | body: Padding( 18 | padding: const EdgeInsets.all(10.0), 19 | child: ListView(children: [ 20 | Padding( 21 | padding: const EdgeInsets.symmetric(horizontal: 10), 22 | child: ElevatedButton( 23 | onPressed: _createCrashReport, 24 | child: const Text("Create crash report"), 25 | )), 26 | const SizedBox(height: 10), 27 | Padding( 28 | padding: const EdgeInsets.symmetric(horizontal: 10), 29 | child: ElevatedButton( 30 | onPressed: _createCrashReportWithLogs, 31 | child: const Text("Create crash report with logs"), 32 | )), 33 | const SizedBox(height: 10), 34 | const Text( 35 | "Check your Crashlytics dashboard in Firebase to see the crash report details!") 36 | ]))); 37 | } 38 | 39 | Future _createCrashReport() async { 40 | FirebaseCrashlytics.instance 41 | .recordError(Exception("Test"), StackTrace.current, fatal: true); 42 | } 43 | 44 | Future _createCrashReportWithLogs() async { 45 | FirebaseCrashlytics.instance.log("This is a log message"); 46 | FirebaseCrashlytics.instance 47 | .recordError(Exception("Test"), StackTrace.current, fatal: true); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 34 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /.firebase/hosting.YnVpbGRcd2Vi.cache: -------------------------------------------------------------------------------- 1 | cors.json,1655811477171,ad45ca0264c9c9e392669e135b28b6c11585424f346c9813a57e53c00e147bbd 2 | favicon.png,1633551548067,0cab6e3dd5a9f008afdd133e1e1207cf65f2f2a10eb6712e3c209d8a5f76425a 3 | flutter_service_worker.js,1664827329702,32c181e2392b8d455c86227e0e64d915d432661d4847324a3dde7e75d4562c05 4 | flutter.js,1664827278171,3b3a07d4c55d59c5461929dc37484dec4d38c90aca67f7c044eb85d9524889e6 5 | manifest.json,1653129654720,e3caad1c9bf25d751519a9a6eb9149cf4c17930377147c770fd755192ac071f8 6 | index.html,1664827328157,78650bbfbc4e04cce9cb7b0c87090102d1fb427524a46d33a3b8f8d35356f61d 7 | version.json,1664827327447,22b355cdc64db49cf42cc5d5b4f56d12de7149cfc0ed882f6ad6399d3bbee37d 8 | assets/AssetManifest.json,1664827327921,7166bd78ba256a204fd30cdfd73655fe4e006a756bc3aa3a338363f0735359b7 9 | assets/FontManifest.json,1664827327921,638dde6f87e8796f3054f78065f73846fc5e170e081d2501d08e3ceaa300edb5 10 | assets/res/github.png,1655404901638,40e68e7c2e9cd3b107e8ed249cb558e600fca1d34717115e5c3e5f6825791d42 11 | assets/res/medium.png,1655404901639,6908aad00b7ffe136983848b34698c39e2a50e1c6e44d4424501f11692f7401c 12 | assets/shaders/ink_sparkle.frag,1664827328096,595b73faf02d89e07dff4a6fb31f078e618906c8b1ea5a2aacc5f14cc43276da 13 | icons/Icon-192.png,1633551548068,eaf2464bfb1d192fdd192a616f7b858dee456d573c6ec619648a1dcf2bdddfa6 14 | icons/Icon-512.png,1633551548069,9cf4cd298ae95acc1f25e97d88aa3f6bbfdf40867ea0f8a854c4393f49d56e64 15 | icons/Icon-maskable-192.png,1633551618484,196ce9142a3442ab37ae90cd46c3389e4660400c859b81cbb0538a51b39752eb 16 | icons/Icon-maskable-512.png,1633551618480,6833b7c449e0dd24d5e164a53cc4557e643893e675b476b05efcbb9a6aa05bf0 17 | canvaskit/canvaskit.js,1664305029353,1c5e4be41a8a2901d8c9ae4edb5c2bd26c5c4d0564d732a3ce2bef7c6c27bcb0 18 | canvaskit/profiling/canvaskit.js,1664305029419,15d13a02cb0d513cda2f2a2b63df45ad9ebb843723e1380386b016360ffc9ba0 19 | assets/res/firebase_compendium_logo.png,1653173907202,a42f0a329794198304ec65f8c90ff48968bfc7dee3cd062c0ee4ba00a72e84e2 20 | assets/packages/cupertino_icons/assets/CupertinoIcons.ttf,1659652669992,007720e2ea8128f223e5f1a08073b8f40df49b41dac35727107ab73dc4488ae0 21 | assets/NOTICES,1664827327923,4f19f9a8ad934d274ad1e55c6eb65eab6f6bc59bb5bbadc84497cbc5f79d5595 22 | assets/fonts/MaterialIcons-Regular.otf,1661633660199,6c5b450bbaa24bf30f1a1c111fe2be1e9c2cb23dde6fa9ee8b3609e812302aed 23 | main.dart.js,1664827326480,1b4f25a9c84caa02b5d372fda37559446e45dca6416c8f2ea878e6e92dc6b76d 24 | canvaskit/canvaskit.wasm,1664305029406,5ead4a7a5f1445e19dbf4515ce48c88ad7070b05c4c318e8a73f83917862aa16 25 | canvaskit/profiling/canvaskit.wasm,1664305029463,92eb89423488999d48294283d3905d1040b96088d7e3c243bf109dbd1bb29ee0 26 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /lib/firebase/firestore.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:cloud_firestore/cloud_firestore.dart'; 4 | 5 | class Firestore { 6 | // just a simple get 7 | static Future> getAllEntries(String collection) async { 8 | return (await FirebaseFirestore.instance.collection(collection).get()) 9 | .docs 10 | .map((item) => Car.fromMap(item.data())) 11 | .toList(); 12 | } 13 | 14 | // get with custom order 15 | static Future> getAllEntriesSortedByName(String collection) async { 16 | return (await FirebaseFirestore.instance 17 | .collection(collection) 18 | .orderBy("manufacturer", descending: false) 19 | .get()) 20 | .docs 21 | .map((item) => Car.fromMap(item.data())) 22 | .toList(); 23 | } 24 | 25 | // get with filter 26 | static Future> getAllEntriesFilteredByPrice( 27 | String collection) async { 28 | return (await FirebaseFirestore.instance 29 | .collection(collection) 30 | .where("price", isGreaterThan: 60000) 31 | .get()) 32 | .docs 33 | .map((item) => Car.fromMap(item.data())) 34 | .toList(); 35 | } 36 | 37 | static Future addEntryWithAutogeneratedId( 38 | String collection, Map data) async { 39 | await FirebaseFirestore.instance.collection(collection).add(data); 40 | } 41 | 42 | // updates an existing entry (missing fields won't be touched on update), document must exist 43 | static Future updateEntryWithId( 44 | String collection, String documentId, Map data) async { 45 | await FirebaseFirestore.instance 46 | .collection(collection) 47 | .doc(documentId) 48 | .update(data); 49 | } 50 | 51 | // adds or updates an existing entry (missing fields will be deleted on update!), document will be created if needed 52 | static Future addOrUpdateWithId( 53 | String collection, String documentId, Map data) async { 54 | await FirebaseFirestore.instance 55 | .collection(collection) 56 | .doc(documentId) 57 | .set(data); 58 | } 59 | 60 | // deletes the entry with the given document id 61 | static Future deleteEntry(String collection, String documentId) async { 62 | await FirebaseFirestore.instance 63 | .collection(collection) 64 | .doc(documentId) 65 | .delete(); 66 | } 67 | } 68 | 69 | class Car { 70 | Car({ 71 | this.engine, 72 | required this.manufacturer, 73 | required this.price, 74 | }); 75 | 76 | final Engine? engine; 77 | final String manufacturer; 78 | final int price; 79 | 80 | factory Car.fromJson(String str) => Car.fromMap(json.decode(str)); 81 | 82 | String toJson() => json.encode(toMap()); 83 | 84 | factory Car.fromMap(Map json) => Car( 85 | engine: json["engine"] == null ? null : Engine.fromMap(json["engine"]), 86 | manufacturer: json["manufacturer"], 87 | price: json["price"], 88 | ); 89 | 90 | Map toMap() => { 91 | "engine": engine?.toMap(), 92 | "manufacturer": manufacturer, 93 | "price": price, 94 | }; 95 | 96 | @override 97 | String toString() { 98 | return "$manufacturer ($price€), ${engine!.cylinders} cylinders, ${engine!.horsePower} hp!"; 99 | } 100 | } 101 | 102 | class Engine { 103 | Engine({ 104 | required this.horsePower, 105 | required this.cylinders, 106 | }); 107 | 108 | final int horsePower; 109 | final int cylinders; 110 | 111 | factory Engine.fromJson(String str) => Engine.fromMap(json.decode(str)); 112 | 113 | String toJson() => json.encode(toMap()); 114 | 115 | factory Engine.fromMap(Map json) => Engine( 116 | horsePower: json["horse_power"], 117 | cylinders: json["cylinders"], 118 | ); 119 | 120 | Map toMap() => { 121 | "horse_power": horsePower, 122 | "cylinders": cylinders, 123 | }; 124 | } 125 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Flutter Firebase Compendium Demo Application 2 | 3 | ![The Flutter Firebase Compendium](res/firebase_compendium_logo.png) 4 | 5 | This is the companion app of the Flutter Firebase Compendium with code examples. 6 | 7 | The Flutter Firebase Compendium is a detailled introduction for Flutter developers to work with Firebase. It explains how to use Firebase services from a Flutter application. Check out [my ebook](https://xeladu.gumroad.com/l/ffc) with many details that will save you many hours of research time to develop your apps quicker. You can learn more about it [here](https://flutter-firebase.quickcoder.org). 8 | 9 | ## Content 10 | 11 | - [Firebase project setup](https://quickcoder.org/firebase-flutter-setup/) 12 | - [Firebase Authentication](https://quickcoder.org/firebase-auth/) 13 | - [Firebase Cloud Firestore](https://quickcoder.org/firebase-firestore/) 14 | - [Firebase Cloud Functions](https://quickcoder.org/firebase-functions/) 15 | - [Firebase Storage](https://quickcoder.org/firebase-storage/) 16 | - [Firebase App Check](https://quickcoder.org/firebase-app-check/) 17 | - [Firebase Remote Config](https://quickcoder.org/firebase-remote-config/) 18 | - [Firebase Hosting](https://quickcoder.org/firebase-hosting/) 19 | - [Firebase Crashlytics](https://quickcoder.org/how-to-monitor-your-mobile-apps-with-firebase-crashlytics/) 20 | 21 | ## How to run the code 22 | 23 | The code uses Firebase as a backend but the Firebase configuration is not included. You have to add it yourself because there are paid features that might cause costs. Refer to [this article](https://quickcoder.org/firebase-flutter-setup/) above on how to perform the necessary steps in detail. 24 | 25 | 1. Create a Firebase project 26 | 2. Install [Firebase CLI](https://firebase.google.com/docs/cli) 27 | 3. Install [FlutterFire CLI](https://pub.dev/packages/flutterfire_cli) 28 | 4. Check out the code 29 | 5. Execute `firebase login` from the app root folder and log into your created Firebase project 30 | 6. Execute `flutterfire configure` from the app root folder and use your created Firebase project 31 | 7. A file `firebase_options.dart` will be created in your `lib` folder 32 | 8. (**Authentication only**) Activate the sign-in providers Email/Password and Google 33 | 9. (**Cloud Functions only**) Execute `firebase deploy --only functions` to deploy the demo functions. You might need to run `npm install` from inside the functions folder to make it work. You need to adapt the link in `functions_page.dart` according to your Firebase instance. 34 | 10. (**Storage and Cloud Firestore only**) Set security rules for Storage and Firestore 35 | 11. (**App Check only**) Register an attestation provider and enforce App Check 36 | 12. (**Remote Config only**) Create parameters with conditions for Remote Config 37 | 13. Run the app 38 | 39 | ## Hints 40 | 41 | - 💡 Social sign-ins only works on web platform without additional configurations 42 | - 💡 You need to replace the link on `functions_page.dart` according to your deployed function link! 43 | - 💡 Don't forget to set the security rules for Storage and Firestore! 44 | - 💡 To get file downloads from Firebase Storage work on the web platform, you need to set specific [CORS rules](https://firebase.google.com/docs/storage/web/download-files#cors_configuration)! 45 | - 💡 [SafetyNet deprecated, supported until June 2024!](https://developer.android.com/training/safetynet/deprecation-timeline) 46 | - 💡 Play Integrity provider for Android only works for apps that are distributed via Google Play! 47 | 48 | ## Platforms 49 | 50 | Overview of supported platforms of the used [Firebase packages](https://firebase.google.com/docs/flutter/setup?platform=ios#add-plugins). 51 | 52 | ✔ - supported ❌ - not supported 53 | 54 | ||Android|iOS|Web|MacOS|Windows|Linux| 55 | |---|:-:|:-:|:-:|:-:|:-:|:-:| 56 | |[Authentication](https://pub.dev/packages/firebase_auth)| ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | 57 | |[Firestore](https://pub.dev/packages/cloud_firestore)| ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | 58 | |[Functions](https://pub.dev/packages/cloud_functions)| ✔ | ✔ | ✔ | ✔ | ❌ | ❌ | 59 | |[Storage](https://pub.dev/packages/firebase_storage)| ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | 60 | |[App Check](https://pub.dev/packages/firebase_app_check)| ✔ | ✔ | ✔ | ✔ | ❌ | ❌ | 61 | |[Remote Config](https://pub.dev/packages/firebase_remote_config)| ✔ | ✔ | ✔ | ✔ | ❌ | ❌ | 62 | |[Crashlytics](https://pub.dev/packages/firebase_crashlytics)| ✔ | ✔ | ❌ | ✔ | ❌ | ❌ | 63 | 64 | ## About me 65 | 66 | - Follow me on [Medium](https://xeladu.medium.com) 67 | - Visit my [QuickCoder blog](https://quickcoder.org) 68 | - Check out my [digital products](https://xeladu.gumroad.com) 69 | -------------------------------------------------------------------------------- /lib/pages/functions_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:dio/dio.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_firebase/firebase/functions.dart'; 4 | 5 | class FunctionsPage extends StatefulWidget { 6 | const FunctionsPage({super.key}); 7 | 8 | @override 9 | State createState() => _State(); 10 | } 11 | 12 | class _State extends State { 13 | String _upperText = ""; 14 | String _lowerText = ""; 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return Scaffold( 19 | appBar: 20 | AppBar(title: const Center(child: Text("Firebase Cloud Functions"))), 21 | body: Padding( 22 | padding: const EdgeInsets.all(10.0), 23 | child: ListView(children: [ 24 | Card( 25 | color: Colors.grey.shade300, 26 | child: Column(children: [ 27 | Container(height: 10), 28 | const Padding( 29 | padding: EdgeInsets.symmetric(horizontal: 10), 30 | child: Text( 31 | "Convert text to upper case by calling a cloud function", 32 | textAlign: TextAlign.center, 33 | style: TextStyle( 34 | fontSize: 16, fontWeight: FontWeight.bold))), 35 | Container(height: 10), 36 | Padding( 37 | padding: const EdgeInsets.symmetric(horizontal: 10), 38 | child: TextField( 39 | onChanged: (value) { 40 | setState(() { 41 | _upperText = value; 42 | }); 43 | }, 44 | decoration: const InputDecoration(label: Text("Text"))), 45 | ), 46 | Container(height: 10), 47 | ElevatedButton( 48 | onPressed: () async { 49 | if (_upperText == "") { 50 | ScaffoldMessenger.of(context).showSnackBar( 51 | const SnackBar( 52 | backgroundColor: Colors.red, 53 | content: Text("Please provide some text!"))); 54 | } else { 55 | var res = 56 | await Functions.call("toUpperCase", _upperText); 57 | 58 | if (context.mounted) { 59 | ScaffoldMessenger.of(context).showSnackBar(SnackBar( 60 | backgroundColor: Colors.green, 61 | content: Text(res.data.toString()))); 62 | } 63 | } 64 | }, 65 | child: const Text("Send to cloud function")), 66 | Container(height: 10) 67 | ]), 68 | ), 69 | Card( 70 | color: Colors.grey.shade300, 71 | child: Column(children: [ 72 | Container(height: 10), 73 | const Padding( 74 | padding: EdgeInsets.symmetric(horizontal: 10), 75 | child: Text( 76 | "Convert text to lower case by calling an HTTP endpoint", 77 | textAlign: TextAlign.center, 78 | style: TextStyle( 79 | fontSize: 16, fontWeight: FontWeight.bold))), 80 | Container(height: 10), 81 | Padding( 82 | padding: const EdgeInsets.symmetric(horizontal: 10), 83 | child: TextField( 84 | onChanged: (value) { 85 | setState(() { 86 | _lowerText = value; 87 | }); 88 | }, 89 | decoration: const InputDecoration(label: Text("Text"))), 90 | ), 91 | Container(height: 10), 92 | ElevatedButton( 93 | onPressed: () async { 94 | if (_lowerText == "") { 95 | ScaffoldMessenger.of(context).showSnackBar( 96 | const SnackBar( 97 | backgroundColor: Colors.red, 98 | content: Text("Please provide some text!"))); 99 | } else { 100 | var resp = await Dio().post( 101 | "https://", // <-- replace with your link 102 | options: Options(contentType: "text/plain"), 103 | data: _lowerText); 104 | if (context.mounted) { 105 | ScaffoldMessenger.of(context).showSnackBar(SnackBar( 106 | backgroundColor: resp.statusCode == 200 107 | ? Colors.green 108 | : Colors.red, 109 | content: Text(resp.statusCode == 200 110 | ? resp.data.toString() 111 | : resp.statusMessage!))); 112 | } 113 | } 114 | }, 115 | child: const Text("Send to HTTP endpoint")), 116 | Container(height: 10) 117 | ]), 118 | ) 119 | ])), 120 | ); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /lib/pages/firestore_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_firebase/firebase/firestore.dart'; 3 | 4 | class FirestorePage extends StatefulWidget { 5 | const FirestorePage({super.key}); 6 | 7 | @override 8 | State createState() => _State(); 9 | } 10 | 11 | class _State extends State { 12 | List _dataToDisplay = []; 13 | final List _dummyCars = [ 14 | Car( 15 | manufacturer: "Tesla", 16 | price: 65000, 17 | engine: Engine(cylinders: 0, horsePower: 540)), 18 | Car( 19 | manufacturer: "Ford", 20 | price: 34000, 21 | engine: Engine(cylinders: 4, horsePower: 350)), 22 | Car( 23 | manufacturer: "BMW", 24 | price: 75000, 25 | engine: Engine(cylinders: 6, horsePower: 690)), 26 | Car( 27 | manufacturer: "Mercedes-Benz", 28 | price: 125000, 29 | engine: Engine(cylinders: 8, horsePower: 460)), 30 | Car( 31 | manufacturer: "Audi", 32 | price: 92000, 33 | engine: Engine(cylinders: 8, horsePower: 520)), 34 | ]; 35 | 36 | @override 37 | Widget build(BuildContext context) { 38 | return Scaffold( 39 | appBar: AppBar(title: const Center(child: Text("Firebase Firestore"))), 40 | body: Padding( 41 | padding: const EdgeInsets.all(10.0), 42 | child: Column(children: [ 43 | Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ 44 | Container( 45 | color: Colors.grey.shade300, 46 | child: IconButton( 47 | onPressed: () async { 48 | await Firestore.addOrUpdateWithId( 49 | "cars", "0", _dummyCars[0].toMap()); 50 | await Firestore.addOrUpdateWithId( 51 | "cars", "1", _dummyCars[1].toMap()); 52 | await Firestore.addOrUpdateWithId( 53 | "cars", "2", _dummyCars[2].toMap()); 54 | await Firestore.addOrUpdateWithId( 55 | "cars", "3", _dummyCars[3].toMap()); 56 | await Firestore.addOrUpdateWithId( 57 | "cars", "4", _dummyCars[4].toMap()); 58 | 59 | _dataToDisplay = await Firestore.getAllEntries("cars"); 60 | setState(() {}); 61 | 62 | if (context.mounted) { 63 | ScaffoldMessenger.of(context).showSnackBar( 64 | const SnackBar( 65 | backgroundColor: Colors.green, 66 | content: Text("Dummy data added!"))); 67 | } 68 | }, 69 | icon: Icon(Icons.add, 70 | color: Theme.of(context).colorScheme.secondary)), 71 | ), 72 | Container( 73 | color: Colors.grey.shade300, 74 | child: IconButton( 75 | onPressed: () async { 76 | await Firestore.deleteEntry("cars", "4"); 77 | await Firestore.deleteEntry("cars", "3"); 78 | await Firestore.deleteEntry("cars", "2"); 79 | await Firestore.deleteEntry("cars", "1"); 80 | await Firestore.deleteEntry("cars", "0"); 81 | 82 | _dataToDisplay = await Firestore.getAllEntries("cars"); 83 | setState(() {}); 84 | 85 | if (context.mounted) { 86 | ScaffoldMessenger.of(context).showSnackBar( 87 | const SnackBar( 88 | backgroundColor: Colors.green, 89 | content: Text("All data deleted!"))); 90 | } 91 | }, 92 | icon: Icon(Icons.delete, 93 | color: Theme.of(context).colorScheme.secondary)), 94 | ), 95 | Container( 96 | color: Colors.grey.shade300, 97 | child: IconButton( 98 | onPressed: () async { 99 | _dataToDisplay = 100 | await Firestore.getAllEntriesSortedByName("cars"); 101 | setState(() {}); 102 | 103 | if (context.mounted) { 104 | ScaffoldMessenger.of(context).showSnackBar( 105 | const SnackBar( 106 | backgroundColor: Colors.green, 107 | content: Text("Data sorted by name"))); 108 | } 109 | }, 110 | icon: Icon(Icons.sort_by_alpha, 111 | color: Theme.of(context).colorScheme.secondary)), 112 | ), 113 | Container( 114 | color: Colors.grey.shade300, 115 | child: IconButton( 116 | onPressed: () async { 117 | _dataToDisplay = 118 | await Firestore.getAllEntriesFilteredByPrice( 119 | "cars"); 120 | setState(() {}); 121 | 122 | if (context.mounted) { 123 | ScaffoldMessenger.of(context).showSnackBar( 124 | const SnackBar( 125 | backgroundColor: Colors.green, 126 | content: 127 | Text("Data filtered by price > 60000"))); 128 | } 129 | }, 130 | icon: Icon(Icons.filter_alt, 131 | color: Theme.of(context).colorScheme.secondary)), 132 | ), 133 | ]), 134 | Container(height: 10), 135 | (_dataToDisplay.isEmpty) 136 | ? const Text("No data") 137 | : Expanded( 138 | child: ListView.builder( 139 | itemCount: _dataToDisplay.length, 140 | itemBuilder: (ctx, index) { 141 | return Text(_dataToDisplay[index].toString()); 142 | })) 143 | ]))); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /lib/pages/storage_page.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:firebase_storage/firebase_storage.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_firebase/firebase/storage.dart'; 6 | import 'package:flutter_firebase/widgets/file_widget.dart'; 7 | import 'package:image_picker/image_picker.dart'; 8 | 9 | class StoragePage extends StatefulWidget { 10 | const StoragePage({super.key}); 11 | 12 | @override 13 | State createState() => _State(); 14 | } 15 | 16 | class _State extends State { 17 | bool _uploadRunning = false; 18 | String _buttonCaption = "Select file to upload"; 19 | UploadTask? _task; 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | return Scaffold( 24 | appBar: AppBar(title: const Center(child: Text("Firebase Storage"))), 25 | body: Padding( 26 | padding: const EdgeInsets.all(10.0), 27 | child: ListView(children: [ 28 | Card( 29 | color: Colors.grey.shade300, 30 | child: Column(children: [ 31 | Container(height: 10), 32 | const Padding( 33 | padding: EdgeInsets.symmetric(horizontal: 10), 34 | child: Text("Upload a file to storage", 35 | textAlign: TextAlign.center, 36 | style: TextStyle( 37 | fontSize: 16, fontWeight: FontWeight.bold))), 38 | Container(height: 10), 39 | Row(mainAxisAlignment: MainAxisAlignment.center, children: [ 40 | ElevatedButton( 41 | onPressed: _uploadRunning 42 | ? null 43 | : () async { 44 | var img = await _pickImage(); 45 | if (img == null) return; 46 | 47 | try { 48 | _task = Storage.uploadItem( 49 | File(img.path), img.name); 50 | 51 | _uploadRunning = true; 52 | setState(() {}); 53 | 54 | _task!.snapshotEvents.listen((snapshot) { 55 | if (snapshot.state == TaskState.running) { 56 | _buttonCaption = 57 | "Uploading ... ${(100.0 * (snapshot.bytesTransferred / snapshot.totalBytes)).toStringAsFixed(0)}%"; 58 | _uploadRunning = true; 59 | setState(() {}); 60 | return; 61 | } 62 | 63 | if (snapshot.state == TaskState.success) { 64 | _uploadRunning = false; 65 | _buttonCaption = 66 | "Select file to upload"; 67 | _task = null; 68 | setState(() {}); 69 | return; 70 | } 71 | }); 72 | } on FirebaseException catch (ex) { 73 | if (context.mounted) { 74 | ScaffoldMessenger.of(context) 75 | .showSnackBar(SnackBar( 76 | backgroundColor: Colors.red, 77 | content: Text(ex.message!))); 78 | } 79 | } 80 | }, 81 | child: Text(_buttonCaption)), 82 | Container(width: 10), 83 | if (_uploadRunning && _task != null) 84 | IconButton( 85 | onPressed: () async { 86 | await _task!.cancel(); 87 | _uploadRunning = false; 88 | _buttonCaption = "Select file to upload"; 89 | setState(() {}); 90 | }, 91 | icon: const Icon(Icons.stop_circle_outlined, 92 | size: 36, color: Colors.blueAccent)) 93 | ]), 94 | Container(height: 10) 95 | ])), 96 | Container(height: 10), 97 | FutureBuilder( 98 | future: Storage.getData(), 99 | initialData: const [], 100 | builder: (ctx, snapshot) { 101 | if (snapshot.connectionState == ConnectionState.done) { 102 | if (snapshot.hasError) { 103 | return Center(child: Text(snapshot.error.toString())); 104 | } else { 105 | if (_uploadRunning) { 106 | return const Center( 107 | child: CircularProgressIndicator()); 108 | } 109 | 110 | var data = snapshot.data as List; 111 | if (data.isEmpty) { 112 | return Card( 113 | color: Colors.grey.shade300, 114 | child: const Padding( 115 | padding: EdgeInsets.all(10.0), 116 | child: Center( 117 | child: Text( 118 | "No data, please upload some files!")))); 119 | } else { 120 | return Column( 121 | children: data 122 | .map((item) => FileWidget( 123 | content: item.content, 124 | fileName: item.name, 125 | uploadDate: item.uploadDate, 126 | deleteFunction: () async { 127 | await Storage.deleteItem( 128 | item.reference); 129 | 130 | setState(() {}); 131 | }, 132 | )) 133 | .toList()); 134 | } 135 | } 136 | } 137 | 138 | return const Center(child: CircularProgressIndicator()); 139 | }) 140 | ]))); 141 | } 142 | 143 | Future _pickImage() async { 144 | final ImagePicker picker = ImagePicker(); 145 | 146 | return await picker.pickImage(source: ImageSource.gallery); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_core/firebase_core.dart'; 2 | import 'package:firebase_remote_config/firebase_remote_config.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_firebase/pages/auth_page.dart'; 5 | import 'package:flutter_firebase/pages/crashlytics_page.dart'; 6 | import 'package:flutter_firebase/pages/firestore_page.dart'; 7 | import 'package:flutter_firebase/pages/functions_page.dart'; 8 | import 'package:flutter_firebase/pages/remote_config_page.dart'; 9 | import 'package:flutter_firebase/pages/storage_page.dart'; 10 | import 'package:firebase_app_check/firebase_app_check.dart'; 11 | import 'package:url_launcher/url_launcher.dart'; 12 | 13 | import 'firebase_options.dart'; 14 | 15 | Future main() async { 16 | WidgetsFlutterBinding.ensureInitialized(); 17 | 18 | await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); 19 | 20 | await FirebaseAppCheck.instance.activate(); 21 | 22 | // do not use these durations in production as the server limit will be reached very quickly! 23 | await FirebaseRemoteConfig.instance.setConfigSettings(RemoteConfigSettings( 24 | fetchTimeout: const Duration(minutes: 1), 25 | minimumFetchInterval: const Duration(minutes: 1), 26 | )); 27 | await FirebaseRemoteConfig.instance 28 | .setDefaults(const {"platformString": "Hello!"}); 29 | 30 | runApp(const MyApp()); 31 | } 32 | 33 | class MyApp extends StatelessWidget { 34 | const MyApp({super.key}); 35 | 36 | @override 37 | Widget build(BuildContext context) { 38 | return MaterialApp( 39 | title: 'Flutter Demo', 40 | debugShowCheckedModeBanner: false, 41 | theme: ThemeData( 42 | primarySwatch: Colors.blue, 43 | scaffoldBackgroundColor: Colors.white, 44 | appBarTheme: const AppBarTheme(backgroundColor: Colors.white)), 45 | home: const HomePage(), 46 | ); 47 | } 48 | } 49 | 50 | class HomePage extends StatefulWidget { 51 | const HomePage({super.key}); 52 | 53 | @override 54 | State createState() => _State(); 55 | } 56 | 57 | class _State extends State { 58 | @override 59 | Widget build(BuildContext context) { 60 | return Scaffold( 61 | appBar: 62 | AppBar(title: const Center(child: Text("Flutter Firebase Demo"))), 63 | body: Center( 64 | child: ListView(children: [ 65 | Padding( 66 | padding: const EdgeInsets.all(10.0), 67 | child: Card( 68 | color: Colors.grey.shade300, 69 | child: Image.asset("res/firebase_compendium_logo.png")), 70 | ), 71 | Padding( 72 | padding: const EdgeInsets.symmetric(horizontal: 12), 73 | child: ElevatedButton( 74 | onPressed: () { 75 | Navigator.of(context).push(MaterialPageRoute( 76 | builder: (context) => const AuthPage())); 77 | }, 78 | child: const Text("Authentication"))), 79 | const SizedBox(height: 10), 80 | Padding( 81 | padding: const EdgeInsets.symmetric(horizontal: 12), 82 | child: ElevatedButton( 83 | onPressed: () { 84 | Navigator.of(context).push(MaterialPageRoute( 85 | builder: (context) => const FirestorePage())); 86 | }, 87 | child: const Text("Cloud Firestore"))), 88 | const SizedBox(height: 10), 89 | Padding( 90 | padding: const EdgeInsets.symmetric(horizontal: 12), 91 | child: ElevatedButton( 92 | onPressed: () { 93 | Navigator.of(context).push(MaterialPageRoute( 94 | builder: (context) => const FunctionsPage())); 95 | }, 96 | child: const Text("Cloud Functions"))), 97 | const SizedBox(height: 10), 98 | Padding( 99 | padding: const EdgeInsets.symmetric(horizontal: 12), 100 | child: ElevatedButton( 101 | onPressed: () { 102 | Navigator.of(context).push(MaterialPageRoute( 103 | builder: (context) => const StoragePage())); 104 | }, 105 | child: const Text("Storage"))), 106 | const SizedBox(height: 10), 107 | Padding( 108 | padding: const EdgeInsets.symmetric(horizontal: 12), 109 | child: ElevatedButton( 110 | onPressed: () { 111 | Navigator.of(context).push(MaterialPageRoute( 112 | builder: (context) => const RemoteConfigPage())); 113 | }, 114 | child: const Text("Remote Config"))), 115 | const SizedBox(height: 10), 116 | Padding( 117 | padding: const EdgeInsets.symmetric(horizontal: 12), 118 | child: ElevatedButton( 119 | onPressed: () { 120 | Navigator.of(context).push(MaterialPageRoute( 121 | builder: (context) => const CrashlyticsPage())); 122 | }, 123 | child: const Text("Crashlytics"))), 124 | const SizedBox(height: 10), 125 | Padding( 126 | padding: const EdgeInsets.symmetric(horizontal: 12), 127 | child: Card( 128 | shadowColor: Colors.black, 129 | color: Colors.grey.shade200, 130 | child: Padding( 131 | padding: const EdgeInsets.all(8.0), 132 | child: Column( 133 | crossAxisAlignment: CrossAxisAlignment.start, 134 | children: [ 135 | const Center( 136 | child: Text("THE FLUTTER FIREBASE COMPENDIUM", 137 | style: TextStyle( 138 | fontSize: 20, 139 | fontWeight: FontWeight.bold))), 140 | const SizedBox(height: 8), 141 | const Text("▶ Set up Firebase services in minutes", 142 | style: TextStyle(fontSize: 16)), 143 | const Text("▶ Build Flutter apps backed by Firebase", 144 | style: TextStyle(fontSize: 16)), 145 | const Text( 146 | "▶ Understand pros and cons of Firebase services", 147 | style: TextStyle(fontSize: 16)), 148 | const Text( 149 | "▶ Decide what Firebase features you should use", 150 | style: TextStyle(fontSize: 16)), 151 | const SizedBox(height: 8), 152 | Center( 153 | child: ActionChip( 154 | backgroundColor: Colors.lightBlue.shade200, 155 | avatar: const Icon(Icons.arrow_right_alt), 156 | onPressed: () async { 157 | await launchUrl( 158 | Uri.parse( 159 | "https://xeladu.gumroad.com/l/ffc"), 160 | mode: LaunchMode.externalApplication); 161 | }, 162 | label: const Text("Get it on Gumroad!")), 163 | ) 164 | ]), 165 | ))), 166 | ]))); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /lib/pages/auth_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_auth/firebase_auth.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_firebase/firebase/auth.dart'; 4 | 5 | class AuthPage extends StatefulWidget { 6 | const AuthPage({super.key}); 7 | 8 | @override 9 | State createState() => _State(); 10 | } 11 | 12 | class _State extends State { 13 | String _pwd = ""; 14 | String _mail = ""; 15 | User? _user; 16 | 17 | @override 18 | void initState() { 19 | super.initState(); 20 | 21 | FirebaseAuth.instance.authStateChanges().listen((user) { 22 | setState(() { 23 | _user = user; 24 | }); 25 | }); 26 | } 27 | 28 | @override 29 | Widget build(BuildContext context) { 30 | return Scaffold( 31 | appBar: AppBar(title: const Center(child: Text("Firebase Auth"))), 32 | body: Padding( 33 | padding: const EdgeInsets.all(10.0), 34 | child: Stack(children: [ 35 | ListView(children: [ 36 | Card( 37 | color: Colors.grey.shade300, 38 | child: Column(children: [ 39 | Container(height: 10), 40 | const Text("Email and password", 41 | style: 42 | TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), 43 | Container(height: 10), 44 | Padding( 45 | padding: const EdgeInsets.symmetric(horizontal: 10), 46 | child: TextField( 47 | onChanged: (value) { 48 | setState(() { 49 | _mail = value; 50 | }); 51 | }, 52 | decoration: 53 | const InputDecoration(label: Text("Email"))), 54 | ), 55 | Container(height: 10), 56 | Padding( 57 | padding: const EdgeInsets.symmetric(horizontal: 10), 58 | child: TextField( 59 | onChanged: (value) { 60 | setState(() { 61 | _pwd = value; 62 | }); 63 | }, 64 | decoration: 65 | const InputDecoration(label: Text("Password"))), 66 | ), 67 | Container(height: 10), 68 | Row( 69 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 70 | children: [ 71 | ElevatedButton( 72 | onPressed: () async { 73 | var res = await Auth.mailRegister(_mail, _pwd); 74 | if (context.mounted) { 75 | ScaffoldMessenger.of(context).showSnackBar( 76 | SnackBar( 77 | backgroundColor: res == null 78 | ? Colors.green 79 | : Colors.red, 80 | content: Text(res ?? "Registered!"))); 81 | } 82 | }, 83 | child: const Text("Register")), 84 | ElevatedButton( 85 | onPressed: () async { 86 | var res = await Auth.mailSignIn(_mail, _pwd); 87 | if (context.mounted) { 88 | ScaffoldMessenger.of(context).showSnackBar( 89 | SnackBar( 90 | backgroundColor: res == null 91 | ? Colors.green 92 | : Colors.red, 93 | content: Text(res ?? "Logged in!"))); 94 | } 95 | }, 96 | child: const Text("Login")) 97 | ]), 98 | Container(height: 10) 99 | ]), 100 | ), 101 | Container(height: 10), 102 | Card( 103 | color: Colors.grey.shade300, 104 | child: Column(children: [ 105 | Container(height: 10), 106 | const Text("Login with Google", 107 | style: 108 | TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), 109 | Container(height: 10), 110 | ElevatedButton( 111 | onPressed: () async { 112 | var res = await Auth.googleSignIn(); 113 | if (context.mounted) { 114 | ScaffoldMessenger.of(context).showSnackBar(SnackBar( 115 | backgroundColor: 116 | res == null ? Colors.green : Colors.red, 117 | content: Text(res ?? "Logged in!"))); 118 | } 119 | }, 120 | child: const Text("Login with Google")), 121 | Container(height: 10) 122 | ]), 123 | ), 124 | Container(height: 10), 125 | Card( 126 | color: Colors.grey.shade300, 127 | child: Column(children: [ 128 | Container(height: 10), 129 | const Text("Log out", 130 | style: 131 | TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), 132 | Container(height: 10), 133 | ElevatedButton( 134 | onPressed: () async { 135 | var res = await Auth.signOut(); 136 | if (context.mounted) { 137 | ScaffoldMessenger.of(context).showSnackBar(SnackBar( 138 | backgroundColor: 139 | res == null ? Colors.green : Colors.red, 140 | content: Text(res ?? "Logged out!"))); 141 | } 142 | }, 143 | child: const Text("Sign out")), 144 | Container(height: 10) 145 | ]), 146 | ), 147 | Container(height: 10), 148 | if (_user != null) 149 | Card( 150 | color: Colors.grey.shade300, 151 | child: Padding( 152 | padding: const EdgeInsets.all(10.0), 153 | child: Column( 154 | crossAxisAlignment: CrossAxisAlignment.start, 155 | children: [ 156 | const Text("User data", 157 | style: TextStyle(fontWeight: FontWeight.bold)), 158 | Container(height: 10), 159 | Text("Mail: ${_user?.email}"), 160 | Text("Display Name: ${_user?.displayName}"), 161 | Text("User UID: ${_user?.uid}") 162 | ]), 163 | )) 164 | ]), 165 | Align( 166 | alignment: Alignment.bottomCenter, 167 | child: Text( 168 | _user != null ? "Logged in" : "Logged out", 169 | textAlign: TextAlign.center, 170 | style: TextStyle( 171 | color: _user != null ? Colors.green : Colors.red, 172 | fontSize: 16, 173 | fontWeight: FontWeight.bold), 174 | )) 175 | ])), 176 | ); 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | _flutterfire_internals: 5 | dependency: transitive 6 | description: 7 | name: _flutterfire_internals 8 | sha256: "9371d13b8ee442e3bfc08a24e3a1b3742c839abbfaf5eef11b79c4b862c89bf7" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "1.3.41" 12 | async: 13 | dependency: transitive 14 | description: 15 | name: async 16 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "2.11.0" 20 | boolean_selector: 21 | dependency: transitive 22 | description: 23 | name: boolean_selector 24 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "2.1.1" 28 | characters: 29 | dependency: transitive 30 | description: 31 | name: characters 32 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "1.3.0" 36 | clock: 37 | dependency: transitive 38 | description: 39 | name: clock 40 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "1.1.1" 44 | cloud_firestore: 45 | dependency: "direct main" 46 | description: 47 | name: cloud_firestore 48 | sha256: "0af4f1e0b7f82a2082ad2c886b042595d85c7641616688609dd999d33aeef850" 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "5.4.0" 52 | cloud_firestore_platform_interface: 53 | dependency: transitive 54 | description: 55 | name: cloud_firestore_platform_interface 56 | sha256: "6e82bcaf2b8e33f312dfc7c5e5855376fee538467dd6e58dc41bd13996ff5d64" 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "6.4.0" 60 | cloud_firestore_web: 61 | dependency: transitive 62 | description: 63 | name: cloud_firestore_web 64 | sha256: "38aec6ed732980dea6eec192a25fb55665137edc5c356603d8dc26ff5971f4d8" 65 | url: "https://pub.dev" 66 | source: hosted 67 | version: "4.2.0" 68 | cloud_functions: 69 | dependency: "direct main" 70 | description: 71 | name: cloud_functions 72 | sha256: aae10a494476c2027a11c347b7ab5bbddcd4b24072645e2fad2f344d99aaadff 73 | url: "https://pub.dev" 74 | source: hosted 75 | version: "5.1.0" 76 | cloud_functions_platform_interface: 77 | dependency: transitive 78 | description: 79 | name: cloud_functions_platform_interface 80 | sha256: "55af599345b75626ada89d368654b8dc876149b3cd74c01c4aae414548f8619f" 81 | url: "https://pub.dev" 82 | source: hosted 83 | version: "5.5.34" 84 | cloud_functions_web: 85 | dependency: transitive 86 | description: 87 | name: cloud_functions_web 88 | sha256: de7ee9434d8dfd456ceeede21a5bc444eb5e328ecc3b87d52fd19e04573b12ef 89 | url: "https://pub.dev" 90 | source: hosted 91 | version: "4.9.12" 92 | collection: 93 | dependency: transitive 94 | description: 95 | name: collection 96 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 97 | url: "https://pub.dev" 98 | source: hosted 99 | version: "1.18.0" 100 | cross_file: 101 | dependency: transitive 102 | description: 103 | name: cross_file 104 | sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" 105 | url: "https://pub.dev" 106 | source: hosted 107 | version: "0.3.4+2" 108 | cupertino_icons: 109 | dependency: "direct main" 110 | description: 111 | name: cupertino_icons 112 | sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 113 | url: "https://pub.dev" 114 | source: hosted 115 | version: "1.0.8" 116 | dio: 117 | dependency: "direct main" 118 | description: 119 | name: dio 120 | sha256: "5598aa796bbf4699afd5c67c0f5f6e2ed542afc956884b9cd58c306966efc260" 121 | url: "https://pub.dev" 122 | source: hosted 123 | version: "5.7.0" 124 | dio_web_adapter: 125 | dependency: transitive 126 | description: 127 | name: dio_web_adapter 128 | sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8" 129 | url: "https://pub.dev" 130 | source: hosted 131 | version: "2.0.0" 132 | fake_async: 133 | dependency: transitive 134 | description: 135 | name: fake_async 136 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 137 | url: "https://pub.dev" 138 | source: hosted 139 | version: "1.3.1" 140 | file_selector_linux: 141 | dependency: transitive 142 | description: 143 | name: file_selector_linux 144 | sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492" 145 | url: "https://pub.dev" 146 | source: hosted 147 | version: "0.9.2+1" 148 | file_selector_macos: 149 | dependency: transitive 150 | description: 151 | name: file_selector_macos 152 | sha256: f42eacb83b318e183b1ae24eead1373ab1334084404c8c16e0354f9a3e55d385 153 | url: "https://pub.dev" 154 | source: hosted 155 | version: "0.9.4" 156 | file_selector_platform_interface: 157 | dependency: transitive 158 | description: 159 | name: file_selector_platform_interface 160 | sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b 161 | url: "https://pub.dev" 162 | source: hosted 163 | version: "2.6.2" 164 | file_selector_windows: 165 | dependency: transitive 166 | description: 167 | name: file_selector_windows 168 | sha256: "2ad726953f6e8affbc4df8dc78b77c3b4a060967a291e528ef72ae846c60fb69" 169 | url: "https://pub.dev" 170 | source: hosted 171 | version: "0.9.3+2" 172 | firebase_analytics: 173 | dependency: "direct main" 174 | description: 175 | name: firebase_analytics 176 | sha256: "7e032ade38dec2a92f543ba02c5f72f54ffaa095c60d2132b867eab56de3bc73" 177 | url: "https://pub.dev" 178 | source: hosted 179 | version: "11.3.0" 180 | firebase_analytics_platform_interface: 181 | dependency: transitive 182 | description: 183 | name: firebase_analytics_platform_interface 184 | sha256: b62a2444767d95067a7e36b1d6e335e0b877968574bbbfb656168c46f2e95a13 185 | url: "https://pub.dev" 186 | source: hosted 187 | version: "4.2.2" 188 | firebase_analytics_web: 189 | dependency: transitive 190 | description: 191 | name: firebase_analytics_web 192 | sha256: bad44f71f96cfca6c16c9dd4f70b85f123ddca7d5dd698977449fadf298b1782 193 | url: "https://pub.dev" 194 | source: hosted 195 | version: "0.5.9+2" 196 | firebase_app_check: 197 | dependency: "direct main" 198 | description: 199 | name: firebase_app_check 200 | sha256: a523507988614a0a73a171a151bde91ece403bc8bc061c18b0d09bf19866bb4c 201 | url: "https://pub.dev" 202 | source: hosted 203 | version: "0.3.1" 204 | firebase_app_check_platform_interface: 205 | dependency: transitive 206 | description: 207 | name: firebase_app_check_platform_interface 208 | sha256: "243232c27a498a2cf3980d6b51ac9687a3a8a87ec2a9c657c199b0602795c3b6" 209 | url: "https://pub.dev" 210 | source: hosted 211 | version: "0.1.0+35" 212 | firebase_app_check_web: 213 | dependency: transitive 214 | description: 215 | name: firebase_app_check_web 216 | sha256: "489688f4f465136997dfabb08eb900af42ce7b45649b5ac00969d1b6a80ec451" 217 | url: "https://pub.dev" 218 | source: hosted 219 | version: "0.1.2+13" 220 | firebase_auth: 221 | dependency: "direct main" 222 | description: 223 | name: firebase_auth 224 | sha256: "6f5792bdc208416bfdfbfe3363b78ce01667b6ebc4c5cb47cfa891f2fca45ab7" 225 | url: "https://pub.dev" 226 | source: hosted 227 | version: "5.2.0" 228 | firebase_auth_platform_interface: 229 | dependency: transitive 230 | description: 231 | name: firebase_auth_platform_interface 232 | sha256: "80237bb8a92bb0a5e3b40de1c8dbc80254e49ac9e3907b4b47b8e95ac3dd3fad" 233 | url: "https://pub.dev" 234 | source: hosted 235 | version: "7.4.4" 236 | firebase_auth_web: 237 | dependency: transitive 238 | description: 239 | name: firebase_auth_web 240 | sha256: "9d315491a6be65ea83511cb0e078544a309c39dd54c0ee355c51dbd6d8c03cc8" 241 | url: "https://pub.dev" 242 | source: hosted 243 | version: "5.12.6" 244 | firebase_core: 245 | dependency: "direct main" 246 | description: 247 | name: firebase_core 248 | sha256: "06537da27db981947fa535bb91ca120b4e9cb59cb87278dbdde718558cafc9ff" 249 | url: "https://pub.dev" 250 | source: hosted 251 | version: "3.4.0" 252 | firebase_core_platform_interface: 253 | dependency: transitive 254 | description: 255 | name: firebase_core_platform_interface 256 | sha256: f7d7180c7f99babd4b4c517754d41a09a4943a0f7a69b65c894ca5c68ba66315 257 | url: "https://pub.dev" 258 | source: hosted 259 | version: "5.2.1" 260 | firebase_core_web: 261 | dependency: transitive 262 | description: 263 | name: firebase_core_web 264 | sha256: "362e52457ed2b7b180964769c1e04d1e0ea0259fdf7025fdfedd019d4ae2bd88" 265 | url: "https://pub.dev" 266 | source: hosted 267 | version: "2.17.5" 268 | firebase_crashlytics: 269 | dependency: "direct main" 270 | description: 271 | name: firebase_crashlytics 272 | sha256: "4c9872020c0d97a161362ee6af7000cfdb8666234ddc290a15252ad379bb235a" 273 | url: "https://pub.dev" 274 | source: hosted 275 | version: "4.1.0" 276 | firebase_crashlytics_platform_interface: 277 | dependency: transitive 278 | description: 279 | name: firebase_crashlytics_platform_interface 280 | sha256: ede8a199ff03378857d3c8cbb7fa58d37c27bb5a6b75faf8415ff6925dcaae2a 281 | url: "https://pub.dev" 282 | source: hosted 283 | version: "3.6.41" 284 | firebase_remote_config: 285 | dependency: "direct main" 286 | description: 287 | name: firebase_remote_config 288 | sha256: b5c23fb7f5b8fd2338f512587a8d2714b5b81dc02508a1c16163c51c1aa41991 289 | url: "https://pub.dev" 290 | source: hosted 291 | version: "5.1.0" 292 | firebase_remote_config_platform_interface: 293 | dependency: transitive 294 | description: 295 | name: firebase_remote_config_platform_interface 296 | sha256: "127ebc8b7c905d211396cab3b0984e4436c6350400805d196607043b8984d09c" 297 | url: "https://pub.dev" 298 | source: hosted 299 | version: "1.4.41" 300 | firebase_remote_config_web: 301 | dependency: transitive 302 | description: 303 | name: firebase_remote_config_web 304 | sha256: "29dbff195c6225f957af541d325426f1697710ac36d169431c95bc92d985f4d2" 305 | url: "https://pub.dev" 306 | source: hosted 307 | version: "1.6.13" 308 | firebase_storage: 309 | dependency: "direct main" 310 | description: 311 | name: firebase_storage 312 | sha256: dfc06d783dbc0b6200a4b936d8cdbd826bd1571c959854d14a70259188d96e85 313 | url: "https://pub.dev" 314 | source: hosted 315 | version: "12.2.0" 316 | firebase_storage_platform_interface: 317 | dependency: transitive 318 | description: 319 | name: firebase_storage_platform_interface 320 | sha256: "3da511301b77514dee5370281923fbbc6d5725c2a0b96004c5c45415e067f234" 321 | url: "https://pub.dev" 322 | source: hosted 323 | version: "5.1.28" 324 | firebase_storage_web: 325 | dependency: transitive 326 | description: 327 | name: firebase_storage_web 328 | sha256: "7ad67b1c1c46c995a6bd4f225d240fc9a5fb277fade583631ae38750ffd9be17" 329 | url: "https://pub.dev" 330 | source: hosted 331 | version: "3.9.13" 332 | flutter: 333 | dependency: "direct main" 334 | description: flutter 335 | source: sdk 336 | version: "0.0.0" 337 | flutter_lints: 338 | dependency: "direct dev" 339 | description: 340 | name: flutter_lints 341 | sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" 342 | url: "https://pub.dev" 343 | source: hosted 344 | version: "3.0.2" 345 | flutter_plugin_android_lifecycle: 346 | dependency: transitive 347 | description: 348 | name: flutter_plugin_android_lifecycle 349 | sha256: "9ee02950848f61c4129af3d6ec84a1cfc0e47931abc746b03e7a3bc3e8ff6eda" 350 | url: "https://pub.dev" 351 | source: hosted 352 | version: "2.0.22" 353 | flutter_test: 354 | dependency: "direct dev" 355 | description: flutter 356 | source: sdk 357 | version: "0.0.0" 358 | flutter_web_plugins: 359 | dependency: transitive 360 | description: flutter 361 | source: sdk 362 | version: "0.0.0" 363 | http: 364 | dependency: transitive 365 | description: 366 | name: http 367 | sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 368 | url: "https://pub.dev" 369 | source: hosted 370 | version: "1.2.2" 371 | http_parser: 372 | dependency: transitive 373 | description: 374 | name: http_parser 375 | sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" 376 | url: "https://pub.dev" 377 | source: hosted 378 | version: "4.0.2" 379 | image_picker: 380 | dependency: "direct main" 381 | description: 382 | name: image_picker 383 | sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a" 384 | url: "https://pub.dev" 385 | source: hosted 386 | version: "1.1.2" 387 | image_picker_android: 388 | dependency: transitive 389 | description: 390 | name: image_picker_android 391 | sha256: c0a6763d50b354793d0192afd0a12560b823147d3ded7c6b77daf658fa05cc85 392 | url: "https://pub.dev" 393 | source: hosted 394 | version: "0.8.12+13" 395 | image_picker_for_web: 396 | dependency: transitive 397 | description: 398 | name: image_picker_for_web 399 | sha256: "65d94623e15372c5c51bebbcb820848d7bcb323836e12dfdba60b5d3a8b39e50" 400 | url: "https://pub.dev" 401 | source: hosted 402 | version: "3.0.5" 403 | image_picker_ios: 404 | dependency: transitive 405 | description: 406 | name: image_picker_ios 407 | sha256: "6703696ad49f5c3c8356d576d7ace84d1faf459afb07accbb0fae780753ff447" 408 | url: "https://pub.dev" 409 | source: hosted 410 | version: "0.8.12" 411 | image_picker_linux: 412 | dependency: transitive 413 | description: 414 | name: image_picker_linux 415 | sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa" 416 | url: "https://pub.dev" 417 | source: hosted 418 | version: "0.2.1+1" 419 | image_picker_macos: 420 | dependency: transitive 421 | description: 422 | name: image_picker_macos 423 | sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62" 424 | url: "https://pub.dev" 425 | source: hosted 426 | version: "0.2.1+1" 427 | image_picker_platform_interface: 428 | dependency: transitive 429 | description: 430 | name: image_picker_platform_interface 431 | sha256: "9ec26d410ff46f483c5519c29c02ef0e02e13a543f882b152d4bfd2f06802f80" 432 | url: "https://pub.dev" 433 | source: hosted 434 | version: "2.10.0" 435 | image_picker_windows: 436 | dependency: transitive 437 | description: 438 | name: image_picker_windows 439 | sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb" 440 | url: "https://pub.dev" 441 | source: hosted 442 | version: "0.2.1+1" 443 | intl: 444 | dependency: "direct main" 445 | description: 446 | name: intl 447 | sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf 448 | url: "https://pub.dev" 449 | source: hosted 450 | version: "0.19.0" 451 | leak_tracker: 452 | dependency: transitive 453 | description: 454 | name: leak_tracker 455 | sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" 456 | url: "https://pub.dev" 457 | source: hosted 458 | version: "10.0.5" 459 | leak_tracker_flutter_testing: 460 | dependency: transitive 461 | description: 462 | name: leak_tracker_flutter_testing 463 | sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" 464 | url: "https://pub.dev" 465 | source: hosted 466 | version: "3.0.5" 467 | leak_tracker_testing: 468 | dependency: transitive 469 | description: 470 | name: leak_tracker_testing 471 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" 472 | url: "https://pub.dev" 473 | source: hosted 474 | version: "3.0.1" 475 | lints: 476 | dependency: transitive 477 | description: 478 | name: lints 479 | sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 480 | url: "https://pub.dev" 481 | source: hosted 482 | version: "3.0.0" 483 | matcher: 484 | dependency: transitive 485 | description: 486 | name: matcher 487 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb 488 | url: "https://pub.dev" 489 | source: hosted 490 | version: "0.12.16+1" 491 | material_color_utilities: 492 | dependency: transitive 493 | description: 494 | name: material_color_utilities 495 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec 496 | url: "https://pub.dev" 497 | source: hosted 498 | version: "0.11.1" 499 | meta: 500 | dependency: transitive 501 | description: 502 | name: meta 503 | sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 504 | url: "https://pub.dev" 505 | source: hosted 506 | version: "1.15.0" 507 | mime: 508 | dependency: transitive 509 | description: 510 | name: mime 511 | sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" 512 | url: "https://pub.dev" 513 | source: hosted 514 | version: "1.0.6" 515 | path: 516 | dependency: transitive 517 | description: 518 | name: path 519 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 520 | url: "https://pub.dev" 521 | source: hosted 522 | version: "1.9.0" 523 | plugin_platform_interface: 524 | dependency: transitive 525 | description: 526 | name: plugin_platform_interface 527 | sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" 528 | url: "https://pub.dev" 529 | source: hosted 530 | version: "2.1.8" 531 | sky_engine: 532 | dependency: transitive 533 | description: flutter 534 | source: sdk 535 | version: "0.0.99" 536 | source_span: 537 | dependency: transitive 538 | description: 539 | name: source_span 540 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 541 | url: "https://pub.dev" 542 | source: hosted 543 | version: "1.10.0" 544 | stack_trace: 545 | dependency: transitive 546 | description: 547 | name: stack_trace 548 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 549 | url: "https://pub.dev" 550 | source: hosted 551 | version: "1.11.1" 552 | stream_channel: 553 | dependency: transitive 554 | description: 555 | name: stream_channel 556 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 557 | url: "https://pub.dev" 558 | source: hosted 559 | version: "2.1.2" 560 | string_scanner: 561 | dependency: transitive 562 | description: 563 | name: string_scanner 564 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 565 | url: "https://pub.dev" 566 | source: hosted 567 | version: "1.2.0" 568 | term_glyph: 569 | dependency: transitive 570 | description: 571 | name: term_glyph 572 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 573 | url: "https://pub.dev" 574 | source: hosted 575 | version: "1.2.1" 576 | test_api: 577 | dependency: transitive 578 | description: 579 | name: test_api 580 | sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" 581 | url: "https://pub.dev" 582 | source: hosted 583 | version: "0.7.2" 584 | typed_data: 585 | dependency: transitive 586 | description: 587 | name: typed_data 588 | sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c 589 | url: "https://pub.dev" 590 | source: hosted 591 | version: "1.3.2" 592 | url_launcher: 593 | dependency: "direct main" 594 | description: 595 | name: url_launcher 596 | sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3" 597 | url: "https://pub.dev" 598 | source: hosted 599 | version: "6.3.0" 600 | url_launcher_android: 601 | dependency: transitive 602 | description: 603 | name: url_launcher_android 604 | sha256: e35a698ac302dd68e41f73250bd9517fe3ab5fa4f18fe4647a0872db61bacbab 605 | url: "https://pub.dev" 606 | source: hosted 607 | version: "6.3.10" 608 | url_launcher_ios: 609 | dependency: transitive 610 | description: 611 | name: url_launcher_ios 612 | sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e 613 | url: "https://pub.dev" 614 | source: hosted 615 | version: "6.3.1" 616 | url_launcher_linux: 617 | dependency: transitive 618 | description: 619 | name: url_launcher_linux 620 | sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af 621 | url: "https://pub.dev" 622 | source: hosted 623 | version: "3.2.0" 624 | url_launcher_macos: 625 | dependency: transitive 626 | description: 627 | name: url_launcher_macos 628 | sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de" 629 | url: "https://pub.dev" 630 | source: hosted 631 | version: "3.2.0" 632 | url_launcher_platform_interface: 633 | dependency: transitive 634 | description: 635 | name: url_launcher_platform_interface 636 | sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" 637 | url: "https://pub.dev" 638 | source: hosted 639 | version: "2.3.2" 640 | url_launcher_web: 641 | dependency: transitive 642 | description: 643 | name: url_launcher_web 644 | sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" 645 | url: "https://pub.dev" 646 | source: hosted 647 | version: "2.3.3" 648 | url_launcher_windows: 649 | dependency: transitive 650 | description: 651 | name: url_launcher_windows 652 | sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185" 653 | url: "https://pub.dev" 654 | source: hosted 655 | version: "3.1.2" 656 | vector_math: 657 | dependency: transitive 658 | description: 659 | name: vector_math 660 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 661 | url: "https://pub.dev" 662 | source: hosted 663 | version: "2.1.4" 664 | vm_service: 665 | dependency: transitive 666 | description: 667 | name: vm_service 668 | sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc 669 | url: "https://pub.dev" 670 | source: hosted 671 | version: "14.2.4" 672 | web: 673 | dependency: transitive 674 | description: 675 | name: web 676 | sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" 677 | url: "https://pub.dev" 678 | source: hosted 679 | version: "0.5.1" 680 | sdks: 681 | dart: ">=3.5.0 <4.0.0" 682 | flutter: ">=3.24.0" 683 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 13 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXContainerItemProxy section */ 20 | 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { 21 | isa = PBXContainerItemProxy; 22 | containerPortal = 97C146E61CF9000F007C117D /* Project object */; 23 | proxyType = 1; 24 | remoteGlobalIDString = 97C146ED1CF9000F007C117D; 25 | remoteInfo = Runner; 26 | }; 27 | /* End PBXContainerItemProxy section */ 28 | 29 | /* Begin PBXCopyFilesBuildPhase section */ 30 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 31 | isa = PBXCopyFilesBuildPhase; 32 | buildActionMask = 2147483647; 33 | dstPath = ""; 34 | dstSubfolderSpec = 10; 35 | files = ( 36 | ); 37 | name = "Embed Frameworks"; 38 | runOnlyForDeploymentPostprocessing = 0; 39 | }; 40 | /* End PBXCopyFilesBuildPhase section */ 41 | 42 | /* Begin PBXFileReference section */ 43 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 44 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 45 | 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 46 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 48 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 49 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 50 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 51 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 52 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 53 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 55 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 56 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 57 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | /* End PBXFileReference section */ 59 | 60 | /* Begin PBXFrameworksBuildPhase section */ 61 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 62 | isa = PBXFrameworksBuildPhase; 63 | buildActionMask = 2147483647; 64 | files = ( 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | /* End PBXFrameworksBuildPhase section */ 69 | 70 | /* Begin PBXGroup section */ 71 | 331C8082294A63A400263BE5 /* RunnerTests */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | 331C807B294A618700263BE5 /* RunnerTests.swift */, 75 | ); 76 | path = RunnerTests; 77 | sourceTree = ""; 78 | }; 79 | 9740EEB11CF90186004384FC /* Flutter */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 83 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 84 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 85 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 86 | ); 87 | name = Flutter; 88 | sourceTree = ""; 89 | }; 90 | 97C146E51CF9000F007C117D = { 91 | isa = PBXGroup; 92 | children = ( 93 | 9740EEB11CF90186004384FC /* Flutter */, 94 | 97C146F01CF9000F007C117D /* Runner */, 95 | 97C146EF1CF9000F007C117D /* Products */, 96 | 331C8082294A63A400263BE5 /* RunnerTests */, 97 | ); 98 | sourceTree = ""; 99 | }; 100 | 97C146EF1CF9000F007C117D /* Products */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 97C146EE1CF9000F007C117D /* Runner.app */, 104 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */, 105 | ); 106 | name = Products; 107 | sourceTree = ""; 108 | }; 109 | 97C146F01CF9000F007C117D /* Runner */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 113 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 114 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 115 | 97C147021CF9000F007C117D /* Info.plist */, 116 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 117 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 118 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 119 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 120 | ); 121 | path = Runner; 122 | sourceTree = ""; 123 | }; 124 | /* End PBXGroup section */ 125 | 126 | /* Begin PBXNativeTarget section */ 127 | 331C8080294A63A400263BE5 /* RunnerTests */ = { 128 | isa = PBXNativeTarget; 129 | buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; 130 | buildPhases = ( 131 | 331C807D294A63A400263BE5 /* Sources */, 132 | 331C807F294A63A400263BE5 /* Resources */, 133 | ); 134 | buildRules = ( 135 | ); 136 | dependencies = ( 137 | 331C8086294A63A400263BE5 /* PBXTargetDependency */, 138 | ); 139 | name = RunnerTests; 140 | productName = RunnerTests; 141 | productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; 142 | productType = "com.apple.product-type.bundle.unit-test"; 143 | }; 144 | 97C146ED1CF9000F007C117D /* Runner */ = { 145 | isa = PBXNativeTarget; 146 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 147 | buildPhases = ( 148 | 9740EEB61CF901F6004384FC /* Run Script */, 149 | 97C146EA1CF9000F007C117D /* Sources */, 150 | 97C146EB1CF9000F007C117D /* Frameworks */, 151 | 97C146EC1CF9000F007C117D /* Resources */, 152 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 153 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 154 | ); 155 | buildRules = ( 156 | ); 157 | dependencies = ( 158 | ); 159 | name = Runner; 160 | productName = Runner; 161 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 162 | productType = "com.apple.product-type.application"; 163 | }; 164 | /* End PBXNativeTarget section */ 165 | 166 | /* Begin PBXProject section */ 167 | 97C146E61CF9000F007C117D /* Project object */ = { 168 | isa = PBXProject; 169 | attributes = { 170 | BuildIndependentTargetsInParallel = YES; 171 | LastUpgradeCheck = 1510; 172 | ORGANIZATIONNAME = ""; 173 | TargetAttributes = { 174 | 331C8080294A63A400263BE5 = { 175 | CreatedOnToolsVersion = 14.0; 176 | TestTargetID = 97C146ED1CF9000F007C117D; 177 | }; 178 | 97C146ED1CF9000F007C117D = { 179 | CreatedOnToolsVersion = 7.3.1; 180 | LastSwiftMigration = 1100; 181 | }; 182 | }; 183 | }; 184 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 185 | compatibilityVersion = "Xcode 9.3"; 186 | developmentRegion = en; 187 | hasScannedForEncodings = 0; 188 | knownRegions = ( 189 | en, 190 | Base, 191 | ); 192 | mainGroup = 97C146E51CF9000F007C117D; 193 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 194 | projectDirPath = ""; 195 | projectRoot = ""; 196 | targets = ( 197 | 97C146ED1CF9000F007C117D /* Runner */, 198 | 331C8080294A63A400263BE5 /* RunnerTests */, 199 | ); 200 | }; 201 | /* End PBXProject section */ 202 | 203 | /* Begin PBXResourcesBuildPhase section */ 204 | 331C807F294A63A400263BE5 /* Resources */ = { 205 | isa = PBXResourcesBuildPhase; 206 | buildActionMask = 2147483647; 207 | files = ( 208 | ); 209 | runOnlyForDeploymentPostprocessing = 0; 210 | }; 211 | 97C146EC1CF9000F007C117D /* Resources */ = { 212 | isa = PBXResourcesBuildPhase; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 216 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 217 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 218 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 219 | ); 220 | runOnlyForDeploymentPostprocessing = 0; 221 | }; 222 | /* End PBXResourcesBuildPhase section */ 223 | 224 | /* Begin PBXShellScriptBuildPhase section */ 225 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 226 | isa = PBXShellScriptBuildPhase; 227 | alwaysOutOfDate = 1; 228 | buildActionMask = 2147483647; 229 | files = ( 230 | ); 231 | inputPaths = ( 232 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 233 | ); 234 | name = "Thin Binary"; 235 | outputPaths = ( 236 | ); 237 | runOnlyForDeploymentPostprocessing = 0; 238 | shellPath = /bin/sh; 239 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 240 | }; 241 | 9740EEB61CF901F6004384FC /* Run Script */ = { 242 | isa = PBXShellScriptBuildPhase; 243 | alwaysOutOfDate = 1; 244 | buildActionMask = 2147483647; 245 | files = ( 246 | ); 247 | inputPaths = ( 248 | ); 249 | name = "Run Script"; 250 | outputPaths = ( 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | shellPath = /bin/sh; 254 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 255 | }; 256 | /* End PBXShellScriptBuildPhase section */ 257 | 258 | /* Begin PBXSourcesBuildPhase section */ 259 | 331C807D294A63A400263BE5 /* Sources */ = { 260 | isa = PBXSourcesBuildPhase; 261 | buildActionMask = 2147483647; 262 | files = ( 263 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | }; 267 | 97C146EA1CF9000F007C117D /* Sources */ = { 268 | isa = PBXSourcesBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 272 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 273 | ); 274 | runOnlyForDeploymentPostprocessing = 0; 275 | }; 276 | /* End PBXSourcesBuildPhase section */ 277 | 278 | /* Begin PBXTargetDependency section */ 279 | 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { 280 | isa = PBXTargetDependency; 281 | target = 97C146ED1CF9000F007C117D /* Runner */; 282 | targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; 283 | }; 284 | /* End PBXTargetDependency section */ 285 | 286 | /* Begin PBXVariantGroup section */ 287 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 288 | isa = PBXVariantGroup; 289 | children = ( 290 | 97C146FB1CF9000F007C117D /* Base */, 291 | ); 292 | name = Main.storyboard; 293 | sourceTree = ""; 294 | }; 295 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 296 | isa = PBXVariantGroup; 297 | children = ( 298 | 97C147001CF9000F007C117D /* Base */, 299 | ); 300 | name = LaunchScreen.storyboard; 301 | sourceTree = ""; 302 | }; 303 | /* End PBXVariantGroup section */ 304 | 305 | /* Begin XCBuildConfiguration section */ 306 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 307 | isa = XCBuildConfiguration; 308 | buildSettings = { 309 | ALWAYS_SEARCH_USER_PATHS = NO; 310 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 311 | CLANG_ANALYZER_NONNULL = YES; 312 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 313 | CLANG_CXX_LIBRARY = "libc++"; 314 | CLANG_ENABLE_MODULES = YES; 315 | CLANG_ENABLE_OBJC_ARC = YES; 316 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 317 | CLANG_WARN_BOOL_CONVERSION = YES; 318 | CLANG_WARN_COMMA = YES; 319 | CLANG_WARN_CONSTANT_CONVERSION = YES; 320 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 321 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 322 | CLANG_WARN_EMPTY_BODY = YES; 323 | CLANG_WARN_ENUM_CONVERSION = YES; 324 | CLANG_WARN_INFINITE_RECURSION = YES; 325 | CLANG_WARN_INT_CONVERSION = YES; 326 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 327 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 328 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 329 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 330 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 331 | CLANG_WARN_STRICT_PROTOTYPES = YES; 332 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 333 | CLANG_WARN_UNREACHABLE_CODE = YES; 334 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 335 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 336 | COPY_PHASE_STRIP = NO; 337 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 338 | ENABLE_NS_ASSERTIONS = NO; 339 | ENABLE_STRICT_OBJC_MSGSEND = YES; 340 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 341 | GCC_C_LANGUAGE_STANDARD = gnu99; 342 | GCC_NO_COMMON_BLOCKS = YES; 343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 344 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 345 | GCC_WARN_UNDECLARED_SELECTOR = YES; 346 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 347 | GCC_WARN_UNUSED_FUNCTION = YES; 348 | GCC_WARN_UNUSED_VARIABLE = YES; 349 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 350 | MTL_ENABLE_DEBUG_INFO = NO; 351 | SDKROOT = iphoneos; 352 | SUPPORTED_PLATFORMS = iphoneos; 353 | TARGETED_DEVICE_FAMILY = "1,2"; 354 | VALIDATE_PRODUCT = YES; 355 | }; 356 | name = Profile; 357 | }; 358 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 359 | isa = XCBuildConfiguration; 360 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 361 | buildSettings = { 362 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 363 | CLANG_ENABLE_MODULES = YES; 364 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 365 | ENABLE_BITCODE = NO; 366 | INFOPLIST_FILE = Runner/Info.plist; 367 | LD_RUNPATH_SEARCH_PATHS = ( 368 | "$(inherited)", 369 | "@executable_path/Frameworks", 370 | ); 371 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterFirebase; 372 | PRODUCT_NAME = "$(TARGET_NAME)"; 373 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 374 | SWIFT_VERSION = 5.0; 375 | VERSIONING_SYSTEM = "apple-generic"; 376 | }; 377 | name = Profile; 378 | }; 379 | 331C8088294A63A400263BE5 /* Debug */ = { 380 | isa = XCBuildConfiguration; 381 | buildSettings = { 382 | BUNDLE_LOADER = "$(TEST_HOST)"; 383 | CODE_SIGN_STYLE = Automatic; 384 | CURRENT_PROJECT_VERSION = 1; 385 | GENERATE_INFOPLIST_FILE = YES; 386 | MARKETING_VERSION = 1.0; 387 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterFirebase.RunnerTests; 388 | PRODUCT_NAME = "$(TARGET_NAME)"; 389 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 390 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 391 | SWIFT_VERSION = 5.0; 392 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 393 | }; 394 | name = Debug; 395 | }; 396 | 331C8089294A63A400263BE5 /* Release */ = { 397 | isa = XCBuildConfiguration; 398 | buildSettings = { 399 | BUNDLE_LOADER = "$(TEST_HOST)"; 400 | CODE_SIGN_STYLE = Automatic; 401 | CURRENT_PROJECT_VERSION = 1; 402 | GENERATE_INFOPLIST_FILE = YES; 403 | MARKETING_VERSION = 1.0; 404 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterFirebase.RunnerTests; 405 | PRODUCT_NAME = "$(TARGET_NAME)"; 406 | SWIFT_VERSION = 5.0; 407 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 408 | }; 409 | name = Release; 410 | }; 411 | 331C808A294A63A400263BE5 /* Profile */ = { 412 | isa = XCBuildConfiguration; 413 | buildSettings = { 414 | BUNDLE_LOADER = "$(TEST_HOST)"; 415 | CODE_SIGN_STYLE = Automatic; 416 | CURRENT_PROJECT_VERSION = 1; 417 | GENERATE_INFOPLIST_FILE = YES; 418 | MARKETING_VERSION = 1.0; 419 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterFirebase.RunnerTests; 420 | PRODUCT_NAME = "$(TARGET_NAME)"; 421 | SWIFT_VERSION = 5.0; 422 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 423 | }; 424 | name = Profile; 425 | }; 426 | 97C147031CF9000F007C117D /* Debug */ = { 427 | isa = XCBuildConfiguration; 428 | buildSettings = { 429 | ALWAYS_SEARCH_USER_PATHS = NO; 430 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 431 | CLANG_ANALYZER_NONNULL = YES; 432 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 433 | CLANG_CXX_LIBRARY = "libc++"; 434 | CLANG_ENABLE_MODULES = YES; 435 | CLANG_ENABLE_OBJC_ARC = YES; 436 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 437 | CLANG_WARN_BOOL_CONVERSION = YES; 438 | CLANG_WARN_COMMA = YES; 439 | CLANG_WARN_CONSTANT_CONVERSION = YES; 440 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 441 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 442 | CLANG_WARN_EMPTY_BODY = YES; 443 | CLANG_WARN_ENUM_CONVERSION = YES; 444 | CLANG_WARN_INFINITE_RECURSION = YES; 445 | CLANG_WARN_INT_CONVERSION = YES; 446 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 447 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 448 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 449 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 450 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 451 | CLANG_WARN_STRICT_PROTOTYPES = YES; 452 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 453 | CLANG_WARN_UNREACHABLE_CODE = YES; 454 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 455 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 456 | COPY_PHASE_STRIP = NO; 457 | DEBUG_INFORMATION_FORMAT = dwarf; 458 | ENABLE_STRICT_OBJC_MSGSEND = YES; 459 | ENABLE_TESTABILITY = YES; 460 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 461 | GCC_C_LANGUAGE_STANDARD = gnu99; 462 | GCC_DYNAMIC_NO_PIC = NO; 463 | GCC_NO_COMMON_BLOCKS = YES; 464 | GCC_OPTIMIZATION_LEVEL = 0; 465 | GCC_PREPROCESSOR_DEFINITIONS = ( 466 | "DEBUG=1", 467 | "$(inherited)", 468 | ); 469 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 470 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 471 | GCC_WARN_UNDECLARED_SELECTOR = YES; 472 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 473 | GCC_WARN_UNUSED_FUNCTION = YES; 474 | GCC_WARN_UNUSED_VARIABLE = YES; 475 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 476 | MTL_ENABLE_DEBUG_INFO = YES; 477 | ONLY_ACTIVE_ARCH = YES; 478 | SDKROOT = iphoneos; 479 | TARGETED_DEVICE_FAMILY = "1,2"; 480 | }; 481 | name = Debug; 482 | }; 483 | 97C147041CF9000F007C117D /* Release */ = { 484 | isa = XCBuildConfiguration; 485 | buildSettings = { 486 | ALWAYS_SEARCH_USER_PATHS = NO; 487 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 488 | CLANG_ANALYZER_NONNULL = YES; 489 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 490 | CLANG_CXX_LIBRARY = "libc++"; 491 | CLANG_ENABLE_MODULES = YES; 492 | CLANG_ENABLE_OBJC_ARC = YES; 493 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 494 | CLANG_WARN_BOOL_CONVERSION = YES; 495 | CLANG_WARN_COMMA = YES; 496 | CLANG_WARN_CONSTANT_CONVERSION = YES; 497 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 498 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 499 | CLANG_WARN_EMPTY_BODY = YES; 500 | CLANG_WARN_ENUM_CONVERSION = YES; 501 | CLANG_WARN_INFINITE_RECURSION = YES; 502 | CLANG_WARN_INT_CONVERSION = YES; 503 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 504 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 505 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 506 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 507 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 508 | CLANG_WARN_STRICT_PROTOTYPES = YES; 509 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 510 | CLANG_WARN_UNREACHABLE_CODE = YES; 511 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 512 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 513 | COPY_PHASE_STRIP = NO; 514 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 515 | ENABLE_NS_ASSERTIONS = NO; 516 | ENABLE_STRICT_OBJC_MSGSEND = YES; 517 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 518 | GCC_C_LANGUAGE_STANDARD = gnu99; 519 | GCC_NO_COMMON_BLOCKS = YES; 520 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 521 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 522 | GCC_WARN_UNDECLARED_SELECTOR = YES; 523 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 524 | GCC_WARN_UNUSED_FUNCTION = YES; 525 | GCC_WARN_UNUSED_VARIABLE = YES; 526 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 527 | MTL_ENABLE_DEBUG_INFO = NO; 528 | SDKROOT = iphoneos; 529 | SUPPORTED_PLATFORMS = iphoneos; 530 | SWIFT_COMPILATION_MODE = wholemodule; 531 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 532 | TARGETED_DEVICE_FAMILY = "1,2"; 533 | VALIDATE_PRODUCT = YES; 534 | }; 535 | name = Release; 536 | }; 537 | 97C147061CF9000F007C117D /* Debug */ = { 538 | isa = XCBuildConfiguration; 539 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 540 | buildSettings = { 541 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 542 | CLANG_ENABLE_MODULES = YES; 543 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 544 | ENABLE_BITCODE = NO; 545 | INFOPLIST_FILE = Runner/Info.plist; 546 | LD_RUNPATH_SEARCH_PATHS = ( 547 | "$(inherited)", 548 | "@executable_path/Frameworks", 549 | ); 550 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterFirebase; 551 | PRODUCT_NAME = "$(TARGET_NAME)"; 552 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 553 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 554 | SWIFT_VERSION = 5.0; 555 | VERSIONING_SYSTEM = "apple-generic"; 556 | }; 557 | name = Debug; 558 | }; 559 | 97C147071CF9000F007C117D /* Release */ = { 560 | isa = XCBuildConfiguration; 561 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 562 | buildSettings = { 563 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 564 | CLANG_ENABLE_MODULES = YES; 565 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 566 | ENABLE_BITCODE = NO; 567 | INFOPLIST_FILE = Runner/Info.plist; 568 | LD_RUNPATH_SEARCH_PATHS = ( 569 | "$(inherited)", 570 | "@executable_path/Frameworks", 571 | ); 572 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterFirebase; 573 | PRODUCT_NAME = "$(TARGET_NAME)"; 574 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 575 | SWIFT_VERSION = 5.0; 576 | VERSIONING_SYSTEM = "apple-generic"; 577 | }; 578 | name = Release; 579 | }; 580 | /* End XCBuildConfiguration section */ 581 | 582 | /* Begin XCConfigurationList section */ 583 | 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { 584 | isa = XCConfigurationList; 585 | buildConfigurations = ( 586 | 331C8088294A63A400263BE5 /* Debug */, 587 | 331C8089294A63A400263BE5 /* Release */, 588 | 331C808A294A63A400263BE5 /* Profile */, 589 | ); 590 | defaultConfigurationIsVisible = 0; 591 | defaultConfigurationName = Release; 592 | }; 593 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 594 | isa = XCConfigurationList; 595 | buildConfigurations = ( 596 | 97C147031CF9000F007C117D /* Debug */, 597 | 97C147041CF9000F007C117D /* Release */, 598 | 249021D3217E4FDB00AE95B9 /* Profile */, 599 | ); 600 | defaultConfigurationIsVisible = 0; 601 | defaultConfigurationName = Release; 602 | }; 603 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 604 | isa = XCConfigurationList; 605 | buildConfigurations = ( 606 | 97C147061CF9000F007C117D /* Debug */, 607 | 97C147071CF9000F007C117D /* Release */, 608 | 249021D4217E4FDB00AE95B9 /* Profile */, 609 | ); 610 | defaultConfigurationIsVisible = 0; 611 | defaultConfigurationName = Release; 612 | }; 613 | /* End XCConfigurationList section */ 614 | }; 615 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 616 | } 617 | --------------------------------------------------------------------------------