├── .gitignore
├── .metadata
├── .vscode
└── launch.json
├── README.md
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ ├── google-services.json
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── fireflutter_sample_app
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── 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
│ │ │ └── values
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Podfile
├── Podfile.lock
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── 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-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── GoogleService-Info.plist
│ ├── Info.plist
│ ├── Runner-Bridging-Header.h
│ └── Runner.entitlements
├── keystore.key
├── lib
├── global_variables.dart
├── keys.dart
├── main.dart
├── screens
│ ├── admin
│ │ ├── admin.category.screen.dart
│ │ └── admin.screen.dart
│ ├── forum
│ │ ├── comment.dart
│ │ ├── comment.form.dart
│ │ ├── display_photos.dart
│ │ ├── edit_photos.dart
│ │ ├── photo_upload.dart
│ │ ├── post.edit.screen.dart
│ │ └── post.list.screen.dart
│ ├── home
│ │ └── home.screen.dart
│ ├── login
│ │ └── login.screen.dart
│ ├── phone_auth
│ │ ├── phone_auth.screen.dart
│ │ └── phone_auth_verification_code.screen.dart
│ ├── profile
│ │ └── profile.screen.dart
│ ├── push-notification
│ │ └── push-notification.screen.dart
│ ├── register
│ │ └── register.screen.dart
│ ├── search
│ │ └── search.screen.dart
│ └── settings
│ │ └── settings.screen.dart
└── translations.dart
├── pubspec.lock
├── pubspec.yaml
├── test
└── widget_test.dart
└── test_driver
├── app.dart
├── app_test.dart
└── test_runner.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode/
2 | packages/
3 | # Miscellaneous
4 | *.class
5 | *.log
6 | *.pyc
7 | *.swp
8 | .DS_Store
9 | .atom/
10 | .buildlog/
11 | .history
12 | .svn/
13 |
14 | # IntelliJ related
15 | *.iml
16 | *.ipr
17 | *.iws
18 | .idea/
19 |
20 | # The .vscode folder contains launch configuration and tasks you configure in
21 | # VS Code which you may wish to be included in version control, so this line
22 | # is commented out by default.
23 | #.vscode/
24 |
25 | # Flutter/Dart/Pub related
26 | **/doc/api/
27 | **/ios/Flutter/.last_build_id
28 | .dart_tool/
29 | .flutter-plugins
30 | .flutter-plugins-dependencies
31 | .packages
32 | .pub-cache/
33 | .pub/
34 | /build/
35 |
36 | # Web related
37 | lib/generated_plugin_registrant.dart
38 |
39 | # Symbolication related
40 | app.*.symbols
41 |
42 | # Obfuscation related
43 | app.*.map.json
44 |
--------------------------------------------------------------------------------
/.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: 8874f21e79d7ec66d0457c7ab338348e31b17f1d
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 |
8 | {
9 | "name": "Current Device",
10 | "program": "lib/main.dart",
11 | "request": "launch",
12 | "type": "dart"
13 | },
14 | {
15 | "name": "Pixel 3a - Android",
16 | "request": "launch",
17 | "type": "dart",
18 | "deviceId": "emulator-5554"
19 | },
20 | {
21 | "name": "Simulator - iPhone 11 Pro - 14.0",
22 | "request": "launch",
23 | "type": "dart",
24 | "deviceId": "DD183AE3-66CE-4282-A2BA-ADEBEA771AA8"
25 | },
26 | {
27 | "name": "iPhone 11",
28 | "request": "launch",
29 | "type": "dart",
30 | "deviceId": "00008030-000904C80290802E"
31 | },
32 | {
33 | "name": "iPhone 11 Pro Max",
34 | "request": "launch",
35 | "type": "dart",
36 | "deviceId": "B33AA4A3-1FBA-4FC1-AC49-26465C64EB78"
37 | },
38 | {
39 | "name": "App Instrument Emulator",
40 | "program": "test_driver/app.dart",
41 | "request": "launch",
42 | "type": "dart",
43 | "args": [
44 | "--observatory-port",
45 | "12345",
46 | "--disable-service-auth-codes"
47 | ],
48 | "deviceId": "emulator-5554"
49 | },
50 | {
51 | "name": "App Instrument Simulator",
52 | "program": "test_driver/app.dart",
53 | "request": "launch",
54 | "type": "dart",
55 | "args": [
56 | "--observatory-port",
57 | "12345",
58 | "--disable-service-auth-codes"
59 | ],
60 | "deviceId": "004CE606-8161-441D-8AB7-7FA5DEC5DAF0"
61 | }
62 | ],
63 | "compounds": [
64 | {
65 | "name": "All Devices",
66 | "configurations": [
67 | "Pixel 3a - Android",
68 | "Simulator - iPhone 11 Pro - 14.0",
69 | "iPhone 11"
70 | ],
71 | }
72 | ]
73 | }
74 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FireFlutter Sample App
2 |
3 | This is a sample app to demonstrate how to use [FireFlutter](https://pub.dev/packages/fireflutter) package.
4 |
5 | ## Branches
6 |
7 | - You may refer the branches in the following order to see gradual update of the sample app.
8 | - install-fireflutter. Add fireflutter to Flutter project.
9 | - install-getx. Add GetX package to Flutter project.
10 | - routes. Page routes
11 | - register. User registration.
12 | - register-v2. add more code on register page
13 | - social-login. social login. Google, Apple, Facebook.
14 | - login-with-email-password.
15 | - translations. text translation.
16 | - admin-page. adding admin page.
17 | - category-admin. adding category management page and do the code. For using admin page, yo need to login as admin. Read how to set admin in fireflutter README.md if you don't know.
18 | - post-edit. post create without post update
19 | - photo-upload. file upload code without file delete
20 | - forum-list
21 | - Listing posts of a forum cateogry.
22 | - Post create button
23 | - Inifinite scrolling
24 | - Displaying 'no posts' message if there is no post created under a forum.
25 | - Displaying 'no more posts' message if there is no more posts to fetch.
26 | - forum-list-with-photo
27 | - post-delete.
28 | - comment-crud.
29 | - vote.
30 | - phone-verification
31 | - algolia
32 | - settings
33 | - language-settings
34 | - integration-test. The sample app is following the standard Flutter integration test. You can run and test exactly the same way of Flutter integration test.
35 | - vote-settings. To show or hide like/dislike buttons on each forum. You can test it editing the settings on Firestore.
36 | - forum-subscription
37 |
--------------------------------------------------------------------------------
/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/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 29
30 |
31 | sourceSets {
32 | main.java.srcDirs += 'src/main/kotlin'
33 | }
34 |
35 | lintOptions {
36 | disable 'InvalidPackage'
37 | }
38 |
39 | defaultConfig {
40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 | applicationId "com.sonub.fireflutter"
42 | minSdkVersion 21
43 | targetSdkVersion 29
44 | versionCode flutterVersionCode.toInteger()
45 | versionName flutterVersionName
46 | }
47 |
48 | buildTypes {
49 | release {
50 | // TODO: Add your own signing config for the release build.
51 | // Signing with the debug keys for now, so `flutter run --release` works.
52 | signingConfig signingConfigs.debug
53 | }
54 | }
55 | }
56 |
57 | flutter {
58 | source '../..'
59 | }
60 |
61 | dependencies {
62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
63 | }
64 |
65 | apply plugin: 'com.google.gms.google-services'
--------------------------------------------------------------------------------
/android/app/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "389649476574",
4 | "firebase_url": "https://fireflutter-test.firebaseio.com",
5 | "project_id": "fireflutter-test",
6 | "storage_bucket": "fireflutter-test.appspot.com"
7 | },
8 | "client": [
9 | {
10 | "client_info": {
11 | "mobilesdk_app_id": "1:389649476574:android:325835405d373f0f56cb4f",
12 | "android_client_info": {
13 | "package_name": "com.sonub.fireflutter"
14 | }
15 | },
16 | "oauth_client": [
17 | {
18 | "client_id": "389649476574-efs1rlrnttfvmumpobtitbie4omcqd84.apps.googleusercontent.com",
19 | "client_type": 3
20 | }
21 | ],
22 | "api_key": [
23 | {
24 | "current_key": "AIzaSyB4XDiZZinEC4MpvrZ5YKNxw4OHS1f-vVU"
25 | }
26 | ],
27 | "services": {
28 | "appinvite_service": {
29 | "other_platform_oauth_client": [
30 | {
31 | "client_id": "389649476574-efs1rlrnttfvmumpobtitbie4omcqd84.apps.googleusercontent.com",
32 | "client_type": 3
33 | },
34 | {
35 | "client_id": "389649476574-3pp2tstq9l5k8ecotn228v6b0gl905vp.apps.googleusercontent.com",
36 | "client_type": 2,
37 | "ios_info": {
38 | "bundle_id": "com.sonub.fireflutter"
39 | }
40 | }
41 | ]
42 | }
43 | }
44 | }
45 | ],
46 | "configuration_version": "1"
47 | }
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
13 |
14 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
31 |
32 |
33 |
34 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/example/fireflutter_sample_app/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.sonub.fireflutter
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | SMS APP
3 | 2760886707561630
4 | fb2760886707561630
5 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.5.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | classpath 'com.google.gms:google-services:4.3.3'
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | google()
18 | jcenter()
19 | }
20 | }
21 |
22 | rootProject.buildDir = '../build'
23 | subprojects {
24 | project.buildDir = "${rootProject.buildDir}/${project.name}"
25 | }
26 | subprojects {
27 | project.evaluationDependsOn(':app')
28 | }
29 |
30 | task clean(type: Delete) {
31 | delete rootProject.buildDir
32 | }
33 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 | android.enableR8=true
5 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
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 | 9.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | platform :ios, '11.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 |
34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
35 | end
36 |
37 | post_install do |installer|
38 | installer.pods_project.targets.each do |target|
39 | flutter_additional_ios_build_settings(target)
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - abseil/algorithm (0.20200225.0):
3 | - abseil/algorithm/algorithm (= 0.20200225.0)
4 | - abseil/algorithm/container (= 0.20200225.0)
5 | - abseil/algorithm/algorithm (0.20200225.0):
6 | - abseil/base/config
7 | - abseil/algorithm/container (0.20200225.0):
8 | - abseil/algorithm/algorithm
9 | - abseil/base/core_headers
10 | - abseil/meta/type_traits
11 | - abseil/base (0.20200225.0):
12 | - abseil/base/atomic_hook (= 0.20200225.0)
13 | - abseil/base/base (= 0.20200225.0)
14 | - abseil/base/base_internal (= 0.20200225.0)
15 | - abseil/base/bits (= 0.20200225.0)
16 | - abseil/base/config (= 0.20200225.0)
17 | - abseil/base/core_headers (= 0.20200225.0)
18 | - abseil/base/dynamic_annotations (= 0.20200225.0)
19 | - abseil/base/endian (= 0.20200225.0)
20 | - abseil/base/errno_saver (= 0.20200225.0)
21 | - abseil/base/exponential_biased (= 0.20200225.0)
22 | - abseil/base/log_severity (= 0.20200225.0)
23 | - abseil/base/malloc_internal (= 0.20200225.0)
24 | - abseil/base/periodic_sampler (= 0.20200225.0)
25 | - abseil/base/pretty_function (= 0.20200225.0)
26 | - abseil/base/raw_logging_internal (= 0.20200225.0)
27 | - abseil/base/spinlock_wait (= 0.20200225.0)
28 | - abseil/base/throw_delegate (= 0.20200225.0)
29 | - abseil/base/atomic_hook (0.20200225.0):
30 | - abseil/base/config
31 | - abseil/base/core_headers
32 | - abseil/base/base (0.20200225.0):
33 | - abseil/base/atomic_hook
34 | - abseil/base/base_internal
35 | - abseil/base/config
36 | - abseil/base/core_headers
37 | - abseil/base/dynamic_annotations
38 | - abseil/base/log_severity
39 | - abseil/base/raw_logging_internal
40 | - abseil/base/spinlock_wait
41 | - abseil/meta/type_traits
42 | - abseil/base/base_internal (0.20200225.0):
43 | - abseil/base/config
44 | - abseil/meta/type_traits
45 | - abseil/base/bits (0.20200225.0):
46 | - abseil/base/config
47 | - abseil/base/core_headers
48 | - abseil/base/config (0.20200225.0)
49 | - abseil/base/core_headers (0.20200225.0):
50 | - abseil/base/config
51 | - abseil/base/dynamic_annotations (0.20200225.0)
52 | - abseil/base/endian (0.20200225.0):
53 | - abseil/base/config
54 | - abseil/base/core_headers
55 | - abseil/base/errno_saver (0.20200225.0):
56 | - abseil/base/config
57 | - abseil/base/exponential_biased (0.20200225.0):
58 | - abseil/base/config
59 | - abseil/base/core_headers
60 | - abseil/base/log_severity (0.20200225.0):
61 | - abseil/base/config
62 | - abseil/base/core_headers
63 | - abseil/base/malloc_internal (0.20200225.0):
64 | - abseil/base/base
65 | - abseil/base/base_internal
66 | - abseil/base/config
67 | - abseil/base/core_headers
68 | - abseil/base/dynamic_annotations
69 | - abseil/base/raw_logging_internal
70 | - abseil/base/periodic_sampler (0.20200225.0):
71 | - abseil/base/core_headers
72 | - abseil/base/exponential_biased
73 | - abseil/base/pretty_function (0.20200225.0)
74 | - abseil/base/raw_logging_internal (0.20200225.0):
75 | - abseil/base/atomic_hook
76 | - abseil/base/config
77 | - abseil/base/core_headers
78 | - abseil/base/log_severity
79 | - abseil/base/spinlock_wait (0.20200225.0):
80 | - abseil/base/base_internal
81 | - abseil/base/core_headers
82 | - abseil/base/errno_saver
83 | - abseil/base/throw_delegate (0.20200225.0):
84 | - abseil/base/config
85 | - abseil/base/raw_logging_internal
86 | - abseil/container/compressed_tuple (0.20200225.0):
87 | - abseil/utility/utility
88 | - abseil/container/inlined_vector (0.20200225.0):
89 | - abseil/algorithm/algorithm
90 | - abseil/base/core_headers
91 | - abseil/base/throw_delegate
92 | - abseil/container/inlined_vector_internal
93 | - abseil/memory/memory
94 | - abseil/container/inlined_vector_internal (0.20200225.0):
95 | - abseil/base/core_headers
96 | - abseil/container/compressed_tuple
97 | - abseil/memory/memory
98 | - abseil/meta/type_traits
99 | - abseil/types/span
100 | - abseil/memory (0.20200225.0):
101 | - abseil/memory/memory (= 0.20200225.0)
102 | - abseil/memory/memory (0.20200225.0):
103 | - abseil/base/core_headers
104 | - abseil/meta/type_traits
105 | - abseil/meta (0.20200225.0):
106 | - abseil/meta/type_traits (= 0.20200225.0)
107 | - abseil/meta/type_traits (0.20200225.0):
108 | - abseil/base/config
109 | - abseil/numeric/int128 (0.20200225.0):
110 | - abseil/base/config
111 | - abseil/base/core_headers
112 | - abseil/strings/internal (0.20200225.0):
113 | - abseil/base/config
114 | - abseil/base/core_headers
115 | - abseil/base/endian
116 | - abseil/base/raw_logging_internal
117 | - abseil/meta/type_traits
118 | - abseil/strings/str_format (0.20200225.0):
119 | - abseil/strings/str_format_internal
120 | - abseil/strings/str_format_internal (0.20200225.0):
121 | - abseil/base/config
122 | - abseil/base/core_headers
123 | - abseil/meta/type_traits
124 | - abseil/numeric/int128
125 | - abseil/strings/strings
126 | - abseil/types/span
127 | - abseil/strings/strings (0.20200225.0):
128 | - abseil/base/base
129 | - abseil/base/bits
130 | - abseil/base/config
131 | - abseil/base/core_headers
132 | - abseil/base/endian
133 | - abseil/base/raw_logging_internal
134 | - abseil/base/throw_delegate
135 | - abseil/memory/memory
136 | - abseil/meta/type_traits
137 | - abseil/numeric/int128
138 | - abseil/strings/internal
139 | - abseil/time (0.20200225.0):
140 | - abseil/time/internal (= 0.20200225.0)
141 | - abseil/time/time (= 0.20200225.0)
142 | - abseil/time/internal (0.20200225.0):
143 | - abseil/time/internal/cctz (= 0.20200225.0)
144 | - abseil/time/internal/cctz (0.20200225.0):
145 | - abseil/time/internal/cctz/civil_time (= 0.20200225.0)
146 | - abseil/time/internal/cctz/time_zone (= 0.20200225.0)
147 | - abseil/time/internal/cctz/civil_time (0.20200225.0):
148 | - abseil/base/config
149 | - abseil/time/internal/cctz/time_zone (0.20200225.0):
150 | - abseil/base/config
151 | - abseil/time/internal/cctz/civil_time
152 | - abseil/time/time (0.20200225.0):
153 | - abseil/base/base
154 | - abseil/base/core_headers
155 | - abseil/base/raw_logging_internal
156 | - abseil/numeric/int128
157 | - abseil/strings/strings
158 | - abseil/time/internal/cctz/civil_time
159 | - abseil/time/internal/cctz/time_zone
160 | - abseil/types (0.20200225.0):
161 | - abseil/types/any (= 0.20200225.0)
162 | - abseil/types/bad_any_cast (= 0.20200225.0)
163 | - abseil/types/bad_any_cast_impl (= 0.20200225.0)
164 | - abseil/types/bad_optional_access (= 0.20200225.0)
165 | - abseil/types/bad_variant_access (= 0.20200225.0)
166 | - abseil/types/compare (= 0.20200225.0)
167 | - abseil/types/optional (= 0.20200225.0)
168 | - abseil/types/span (= 0.20200225.0)
169 | - abseil/types/variant (= 0.20200225.0)
170 | - abseil/types/any (0.20200225.0):
171 | - abseil/base/config
172 | - abseil/base/core_headers
173 | - abseil/meta/type_traits
174 | - abseil/types/bad_any_cast
175 | - abseil/utility/utility
176 | - abseil/types/bad_any_cast (0.20200225.0):
177 | - abseil/base/config
178 | - abseil/types/bad_any_cast_impl
179 | - abseil/types/bad_any_cast_impl (0.20200225.0):
180 | - abseil/base/config
181 | - abseil/base/raw_logging_internal
182 | - abseil/types/bad_optional_access (0.20200225.0):
183 | - abseil/base/config
184 | - abseil/base/raw_logging_internal
185 | - abseil/types/bad_variant_access (0.20200225.0):
186 | - abseil/base/config
187 | - abseil/base/raw_logging_internal
188 | - abseil/types/compare (0.20200225.0):
189 | - abseil/base/core_headers
190 | - abseil/meta/type_traits
191 | - abseil/types/optional (0.20200225.0):
192 | - abseil/base/base_internal
193 | - abseil/base/config
194 | - abseil/base/core_headers
195 | - abseil/memory/memory
196 | - abseil/meta/type_traits
197 | - abseil/types/bad_optional_access
198 | - abseil/utility/utility
199 | - abseil/types/span (0.20200225.0):
200 | - abseil/algorithm/algorithm
201 | - abseil/base/core_headers
202 | - abseil/base/throw_delegate
203 | - abseil/meta/type_traits
204 | - abseil/types/variant (0.20200225.0):
205 | - abseil/base/base_internal
206 | - abseil/base/config
207 | - abseil/base/core_headers
208 | - abseil/meta/type_traits
209 | - abseil/types/bad_variant_access
210 | - abseil/utility/utility
211 | - abseil/utility/utility (0.20200225.0):
212 | - abseil/base/base_internal
213 | - abseil/base/config
214 | - abseil/meta/type_traits
215 | - AppAuth (1.4.0):
216 | - AppAuth/Core (= 1.4.0)
217 | - AppAuth/ExternalUserAgent (= 1.4.0)
218 | - AppAuth/Core (1.4.0)
219 | - AppAuth/ExternalUserAgent (1.4.0)
220 | - BoringSSL-GRPC (0.0.7):
221 | - BoringSSL-GRPC/Implementation (= 0.0.7)
222 | - BoringSSL-GRPC/Interface (= 0.0.7)
223 | - BoringSSL-GRPC/Implementation (0.0.7):
224 | - BoringSSL-GRPC/Interface (= 0.0.7)
225 | - BoringSSL-GRPC/Interface (0.0.7)
226 | - cloud_firestore (0.14.1-3):
227 | - Firebase/CoreOnly (~> 6.26.0)
228 | - Firebase/Firestore (~> 6.26.0)
229 | - firebase_core
230 | - Flutter
231 | - FBSDKCoreKit (7.1.1):
232 | - FBSDKCoreKit/Basics (= 7.1.1)
233 | - FBSDKCoreKit/Core (= 7.1.1)
234 | - FBSDKCoreKit/Basics (7.1.1)
235 | - FBSDKCoreKit/Core (7.1.1):
236 | - FBSDKCoreKit/Basics
237 | - FBSDKLoginKit (7.1.1):
238 | - FBSDKLoginKit/Login (= 7.1.1)
239 | - FBSDKLoginKit/Login (7.1.1):
240 | - FBSDKCoreKit (~> 7.1.1)
241 | - Firebase/Auth (6.26.0):
242 | - Firebase/CoreOnly
243 | - FirebaseAuth (~> 6.5.3)
244 | - Firebase/CoreOnly (6.26.0):
245 | - FirebaseCore (= 6.7.2)
246 | - Firebase/Firestore (6.26.0):
247 | - Firebase/CoreOnly
248 | - FirebaseFirestore (~> 1.15.0)
249 | - Firebase/Messaging (6.26.0):
250 | - Firebase/CoreOnly
251 | - FirebaseMessaging (~> 4.4.1)
252 | - Firebase/Storage (6.26.0):
253 | - Firebase/CoreOnly
254 | - FirebaseStorage (~> 3.6.1)
255 | - firebase_auth (0.18.1-2):
256 | - Firebase/Auth (~> 6.26.0)
257 | - Firebase/CoreOnly (~> 6.26.0)
258 | - firebase_core
259 | - Flutter
260 | - firebase_core (0.5.0-1):
261 | - Firebase/CoreOnly (~> 6.26.0)
262 | - Flutter
263 | - firebase_messaging (7.0.3):
264 | - Firebase/CoreOnly (~> 6.26.0)
265 | - Firebase/Messaging (~> 6.26.0)
266 | - firebase_core
267 | - Flutter
268 | - firebase_storage (5.0.0-dev.3):
269 | - Firebase/CoreOnly (~> 6.26.0)
270 | - Firebase/Storage (~> 6.26.0)
271 | - firebase_core
272 | - Flutter
273 | - FirebaseAnalyticsInterop (1.5.0)
274 | - FirebaseAuth (6.5.3):
275 | - FirebaseAuthInterop (~> 1.0)
276 | - FirebaseCore (~> 6.6)
277 | - GoogleUtilities/AppDelegateSwizzler (~> 6.5)
278 | - GoogleUtilities/Environment (~> 6.5)
279 | - GTMSessionFetcher/Core (~> 1.1)
280 | - FirebaseAuthInterop (1.1.0)
281 | - FirebaseCore (6.7.2):
282 | - FirebaseCoreDiagnostics (~> 1.3)
283 | - FirebaseCoreDiagnosticsInterop (~> 1.2)
284 | - GoogleUtilities/Environment (~> 6.5)
285 | - GoogleUtilities/Logger (~> 6.5)
286 | - FirebaseCoreDiagnostics (1.5.0):
287 | - GoogleDataTransport (~> 7.0)
288 | - GoogleUtilities/Environment (~> 6.7)
289 | - GoogleUtilities/Logger (~> 6.7)
290 | - nanopb (~> 1.30905.0)
291 | - FirebaseCoreDiagnosticsInterop (1.2.0)
292 | - FirebaseFirestore (1.15.0):
293 | - abseil/algorithm (= 0.20200225.0)
294 | - abseil/base (= 0.20200225.0)
295 | - abseil/memory (= 0.20200225.0)
296 | - abseil/meta (= 0.20200225.0)
297 | - abseil/strings/strings (= 0.20200225.0)
298 | - abseil/time (= 0.20200225.0)
299 | - abseil/types (= 0.20200225.0)
300 | - FirebaseAuthInterop (~> 1.0)
301 | - FirebaseCore (~> 6.2)
302 | - "gRPC-C++ (~> 1.28.0)"
303 | - leveldb-library (~> 1.22)
304 | - nanopb (~> 1.30905.0)
305 | - FirebaseInstallations (1.3.0):
306 | - FirebaseCore (~> 6.6)
307 | - GoogleUtilities/Environment (~> 6.6)
308 | - GoogleUtilities/UserDefaults (~> 6.6)
309 | - PromisesObjC (~> 1.2)
310 | - FirebaseInstanceID (4.3.4):
311 | - FirebaseCore (~> 6.6)
312 | - FirebaseInstallations (~> 1.0)
313 | - GoogleUtilities/Environment (~> 6.5)
314 | - GoogleUtilities/UserDefaults (~> 6.5)
315 | - FirebaseMessaging (4.4.1):
316 | - FirebaseAnalyticsInterop (~> 1.5)
317 | - FirebaseCore (~> 6.6)
318 | - FirebaseInstanceID (~> 4.3)
319 | - GoogleUtilities/AppDelegateSwizzler (~> 6.5)
320 | - GoogleUtilities/Environment (~> 6.5)
321 | - GoogleUtilities/Reachability (~> 6.5)
322 | - GoogleUtilities/UserDefaults (~> 6.5)
323 | - Protobuf (>= 3.9.2, ~> 3.9)
324 | - FirebaseStorage (3.6.1):
325 | - FirebaseAuthInterop (~> 1.1)
326 | - FirebaseCore (~> 6.6)
327 | - GTMSessionFetcher/Core (~> 1.1)
328 | - Flutter (1.0.0)
329 | - flutter_facebook_auth (0.3.1):
330 | - FBSDKCoreKit (~> 7.1.0)
331 | - FBSDKLoginKit (~> 7.1.0)
332 | - Flutter
333 | - flutter_image_compress (0.0.1):
334 | - Flutter
335 | - Mantle
336 | - SDWebImageWebPCoder
337 | - google_sign_in (0.0.1):
338 | - Flutter
339 | - GoogleSignIn (~> 5.0)
340 | - GoogleDataTransport (7.2.0):
341 | - nanopb (~> 1.30905.0)
342 | - GoogleSignIn (5.0.2):
343 | - AppAuth (~> 1.2)
344 | - GTMAppAuth (~> 1.0)
345 | - GTMSessionFetcher/Core (~> 1.1)
346 | - GoogleUtilities/AppDelegateSwizzler (6.7.2):
347 | - GoogleUtilities/Environment
348 | - GoogleUtilities/Logger
349 | - GoogleUtilities/Network
350 | - GoogleUtilities/Environment (6.7.2):
351 | - PromisesObjC (~> 1.2)
352 | - GoogleUtilities/Logger (6.7.2):
353 | - GoogleUtilities/Environment
354 | - GoogleUtilities/Network (6.7.2):
355 | - GoogleUtilities/Logger
356 | - "GoogleUtilities/NSData+zlib"
357 | - GoogleUtilities/Reachability
358 | - "GoogleUtilities/NSData+zlib (6.7.2)"
359 | - GoogleUtilities/Reachability (6.7.2):
360 | - GoogleUtilities/Logger
361 | - GoogleUtilities/UserDefaults (6.7.2):
362 | - GoogleUtilities/Logger
363 | - "gRPC-C++ (1.28.2)":
364 | - "gRPC-C++/Implementation (= 1.28.2)"
365 | - "gRPC-C++/Interface (= 1.28.2)"
366 | - "gRPC-C++/Implementation (1.28.2)":
367 | - abseil/container/inlined_vector (= 0.20200225.0)
368 | - abseil/memory/memory (= 0.20200225.0)
369 | - abseil/strings/str_format (= 0.20200225.0)
370 | - abseil/strings/strings (= 0.20200225.0)
371 | - abseil/types/optional (= 0.20200225.0)
372 | - "gRPC-C++/Interface (= 1.28.2)"
373 | - gRPC-Core (= 1.28.2)
374 | - "gRPC-C++/Interface (1.28.2)"
375 | - gRPC-Core (1.28.2):
376 | - gRPC-Core/Implementation (= 1.28.2)
377 | - gRPC-Core/Interface (= 1.28.2)
378 | - gRPC-Core/Implementation (1.28.2):
379 | - abseil/container/inlined_vector (= 0.20200225.0)
380 | - abseil/memory/memory (= 0.20200225.0)
381 | - abseil/strings/str_format (= 0.20200225.0)
382 | - abseil/strings/strings (= 0.20200225.0)
383 | - abseil/types/optional (= 0.20200225.0)
384 | - BoringSSL-GRPC (= 0.0.7)
385 | - gRPC-Core/Interface (= 1.28.2)
386 | - gRPC-Core/Interface (1.28.2)
387 | - GTMAppAuth (1.1.0):
388 | - AppAuth/Core (~> 1.4)
389 | - GTMSessionFetcher (~> 1.4)
390 | - GTMSessionFetcher (1.4.0):
391 | - GTMSessionFetcher/Full (= 1.4.0)
392 | - GTMSessionFetcher/Core (1.4.0)
393 | - GTMSessionFetcher/Full (1.4.0):
394 | - GTMSessionFetcher/Core (= 1.4.0)
395 | - image_picker (0.0.1):
396 | - Flutter
397 | - leveldb-library (1.22)
398 | - libwebp (1.1.0):
399 | - libwebp/demux (= 1.1.0)
400 | - libwebp/mux (= 1.1.0)
401 | - libwebp/webp (= 1.1.0)
402 | - libwebp/demux (1.1.0):
403 | - libwebp/webp
404 | - libwebp/mux (1.1.0):
405 | - libwebp/demux
406 | - libwebp/webp (1.1.0)
407 | - Mantle (2.1.6):
408 | - Mantle/extobjc (= 2.1.6)
409 | - Mantle/extobjc (2.1.6)
410 | - nanopb (1.30905.0):
411 | - nanopb/decode (= 1.30905.0)
412 | - nanopb/encode (= 1.30905.0)
413 | - nanopb/decode (1.30905.0)
414 | - nanopb/encode (1.30905.0)
415 | - path_provider (0.0.1):
416 | - Flutter
417 | - "permission_handler (5.0.1+1)":
418 | - Flutter
419 | - PromisesObjC (1.2.11)
420 | - Protobuf (3.13.0)
421 | - SDWebImage/Core (5.9.3)
422 | - SDWebImageWebPCoder (0.6.1):
423 | - libwebp (~> 1.0)
424 | - SDWebImage/Core (~> 5.7)
425 | - sign_in_with_apple (0.0.1):
426 | - Flutter
427 |
428 | DEPENDENCIES:
429 | - cloud_firestore (from `.symlinks/plugins/cloud_firestore/ios`)
430 | - firebase_auth (from `.symlinks/plugins/firebase_auth/ios`)
431 | - firebase_core (from `.symlinks/plugins/firebase_core/ios`)
432 | - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
433 | - firebase_storage (from `.symlinks/plugins/firebase_storage/ios`)
434 | - Flutter (from `Flutter`)
435 | - flutter_facebook_auth (from `.symlinks/plugins/flutter_facebook_auth/ios`)
436 | - flutter_image_compress (from `.symlinks/plugins/flutter_image_compress/ios`)
437 | - google_sign_in (from `.symlinks/plugins/google_sign_in/ios`)
438 | - image_picker (from `.symlinks/plugins/image_picker/ios`)
439 | - path_provider (from `.symlinks/plugins/path_provider/ios`)
440 | - permission_handler (from `.symlinks/plugins/permission_handler/ios`)
441 | - sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`)
442 |
443 | SPEC REPOS:
444 | trunk:
445 | - abseil
446 | - AppAuth
447 | - BoringSSL-GRPC
448 | - FBSDKCoreKit
449 | - FBSDKLoginKit
450 | - Firebase
451 | - FirebaseAnalyticsInterop
452 | - FirebaseAuth
453 | - FirebaseAuthInterop
454 | - FirebaseCore
455 | - FirebaseCoreDiagnostics
456 | - FirebaseCoreDiagnosticsInterop
457 | - FirebaseFirestore
458 | - FirebaseInstallations
459 | - FirebaseInstanceID
460 | - FirebaseMessaging
461 | - FirebaseStorage
462 | - GoogleDataTransport
463 | - GoogleSignIn
464 | - GoogleUtilities
465 | - "gRPC-C++"
466 | - gRPC-Core
467 | - GTMAppAuth
468 | - GTMSessionFetcher
469 | - leveldb-library
470 | - libwebp
471 | - Mantle
472 | - nanopb
473 | - PromisesObjC
474 | - Protobuf
475 | - SDWebImage
476 | - SDWebImageWebPCoder
477 |
478 | EXTERNAL SOURCES:
479 | cloud_firestore:
480 | :path: ".symlinks/plugins/cloud_firestore/ios"
481 | firebase_auth:
482 | :path: ".symlinks/plugins/firebase_auth/ios"
483 | firebase_core:
484 | :path: ".symlinks/plugins/firebase_core/ios"
485 | firebase_messaging:
486 | :path: ".symlinks/plugins/firebase_messaging/ios"
487 | firebase_storage:
488 | :path: ".symlinks/plugins/firebase_storage/ios"
489 | Flutter:
490 | :path: Flutter
491 | flutter_facebook_auth:
492 | :path: ".symlinks/plugins/flutter_facebook_auth/ios"
493 | flutter_image_compress:
494 | :path: ".symlinks/plugins/flutter_image_compress/ios"
495 | google_sign_in:
496 | :path: ".symlinks/plugins/google_sign_in/ios"
497 | image_picker:
498 | :path: ".symlinks/plugins/image_picker/ios"
499 | path_provider:
500 | :path: ".symlinks/plugins/path_provider/ios"
501 | permission_handler:
502 | :path: ".symlinks/plugins/permission_handler/ios"
503 | sign_in_with_apple:
504 | :path: ".symlinks/plugins/sign_in_with_apple/ios"
505 |
506 | SPEC CHECKSUMS:
507 | abseil: 6c8eb7892aefa08d929b39f9bb108e5367e3228f
508 | AppAuth: 31bcec809a638d7bd2f86ea8a52bd45f6e81e7c7
509 | BoringSSL-GRPC: 8edf627ee524575e2f8d19d56f068b448eea3879
510 | cloud_firestore: db3dab8f6a348f0f6ec01c3ba911ec5ac5e0df1a
511 | FBSDKCoreKit: b46507dc8b8cefed31d644e74d7cc30e2a715ef8
512 | FBSDKLoginKit: 1a61d79e2b25e2fc0d03dccab1e34b38bbdf2546
513 | Firebase: 7cf5f9c67f03cb3b606d1d6535286e1080e57eb6
514 | firebase_auth: 8ae6798925da84bf8745668a73c936b148c1b04d
515 | firebase_core: 00e54a4744164a6b5a250b96dd1ad5afaba7a342
516 | firebase_messaging: 666d9994651b1ecf8c582b52dd913f3fa58c17ef
517 | firebase_storage: 1195e13abca4fc81fde62d0fde5d0e9508a398e0
518 | FirebaseAnalyticsInterop: 3f86269c38ae41f47afeb43ebf32a001f58fcdae
519 | FirebaseAuth: 7047aec89c0b17ecd924a550c853f0c27ac6015e
520 | FirebaseAuthInterop: a0f37ae05833af156e72028f648d313f7e7592e9
521 | FirebaseCore: f42e5e5f382cdcf6b617ed737bf6c871a6947b17
522 | FirebaseCoreDiagnostics: 7535fe695737f8c5b350584292a70b7f8ff0357b
523 | FirebaseCoreDiagnosticsInterop: 296e2c5f5314500a850ad0b83e9e7c10b011a850
524 | FirebaseFirestore: 8c158bdde010fa397386333a74570eaef033e62d
525 | FirebaseInstallations: 6f5f680e65dc374397a483c32d1799ba822a395b
526 | FirebaseInstanceID: cef67c4967c7cecb56ea65d8acbb4834825c587b
527 | FirebaseMessaging: 29543feb343b09546ab3aa04d008ee8595b43c44
528 | FirebaseStorage: f4f39ae834a7145963b913f54e2f24a9db1d8fac
529 | Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
530 | flutter_facebook_auth: 85c86b1f574faa5eaacd6de0db6b416fa94b326c
531 | flutter_image_compress: 082f8daaf6c1b0c9fe798251c750ef0ecd98d7ae
532 | google_sign_in: 6bd214b9c154f881422f5fe27b66aaa7bbd580cc
533 | GoogleDataTransport: 672fb0ce96fe7f7f31d43672fca62ad2c9c86f7b
534 | GoogleSignIn: 7137d297ddc022a7e0aa4619c86d72c909fa7213
535 | GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3
536 | "gRPC-C++": 13d8ccef97d5c3c441b7e3c529ef28ebee86fad2
537 | gRPC-Core: 4afa11bfbedf7cdecd04de535a9e046893404ed5
538 | GTMAppAuth: 197a8dabfea5d665224aa00d17f164fc2248dab9
539 | GTMSessionFetcher: 6f5c8abbab8a9bce4bb3f057e317728ec6182b10
540 | image_picker: 9c3312491f862b28d21ecd8fdf0ee14e601b3f09
541 | leveldb-library: 55d93ee664b4007aac644a782d11da33fba316f7
542 | libwebp: 946cb3063cea9236285f7e9a8505d806d30e07f3
543 | Mantle: 4c0ed6ce47c96eccc4dc3bb071deb3def0e2c3be
544 | nanopb: c43f40fadfe79e8b8db116583945847910cbabc9
545 | path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
546 | permission_handler: eac8e15b4a1a3fba55b761d19f3f4e6b005d15b6
547 | PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f
548 | Protobuf: 3dac39b34a08151c6d949560efe3f86134a3f748
549 | SDWebImage: a31ee8e90a97303529e03fb0c333eae0eacb88e9
550 | SDWebImageWebPCoder: d0dac55073088d24b2ac1b191a71a8f8d0adac21
551 | sign_in_with_apple: 34f3f5456a45fd7ac5fb42905e2ad31dae061b4a
552 |
553 | PODFILE CHECKSUM: 7368163408c647b7eb699d0d788ba6718e18fb8d
554 |
555 | COCOAPODS: 1.9.3
556 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 51;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 1A002F1325502EB6006905AA /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1A002F1225502EB6006905AA /* GoogleService-Info.plist */; };
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 | E84AAD398A9C573A9B9B625C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 036B127D606018CCA6000331 /* Pods_Runner.framework */; };
18 | /* End PBXBuildFile section */
19 |
20 | /* Begin PBXCopyFilesBuildPhase section */
21 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
22 | isa = PBXCopyFilesBuildPhase;
23 | buildActionMask = 2147483647;
24 | dstPath = "";
25 | dstSubfolderSpec = 10;
26 | files = (
27 | );
28 | name = "Embed Frameworks";
29 | runOnlyForDeploymentPostprocessing = 0;
30 | };
31 | /* End PBXCopyFilesBuildPhase section */
32 |
33 | /* Begin PBXFileReference section */
34 | 036B127D606018CCA6000331 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
35 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
36 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
37 | 1A002F1225502EB6006905AA /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; };
38 | 1A49C2B825517AC300421ABB /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; };
39 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
40 | 4292FBDDFFC0146FCE7CCAC3 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
41 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
42 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
43 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
44 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
45 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
46 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
47 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
48 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
49 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
50 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
51 | 9F03826D4E37AC736C4FEF01 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; };
52 | A4368E8CD5C23A3966F43655 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; };
53 | /* End PBXFileReference section */
54 |
55 | /* Begin PBXFrameworksBuildPhase section */
56 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
57 | isa = PBXFrameworksBuildPhase;
58 | buildActionMask = 2147483647;
59 | files = (
60 | E84AAD398A9C573A9B9B625C /* Pods_Runner.framework in Frameworks */,
61 | );
62 | runOnlyForDeploymentPostprocessing = 0;
63 | };
64 | /* End PBXFrameworksBuildPhase section */
65 |
66 | /* Begin PBXGroup section */
67 | 9740EEB11CF90186004384FC /* Flutter */ = {
68 | isa = PBXGroup;
69 | children = (
70 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
71 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
72 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
73 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
74 | );
75 | name = Flutter;
76 | sourceTree = "";
77 | };
78 | 97C146E51CF9000F007C117D = {
79 | isa = PBXGroup;
80 | children = (
81 | 9740EEB11CF90186004384FC /* Flutter */,
82 | 97C146F01CF9000F007C117D /* Runner */,
83 | 97C146EF1CF9000F007C117D /* Products */,
84 | CF765A2754216E131ABC0089 /* Pods */,
85 | CF2974DCF16F8776A7B7DCD0 /* Frameworks */,
86 | );
87 | sourceTree = "";
88 | };
89 | 97C146EF1CF9000F007C117D /* Products */ = {
90 | isa = PBXGroup;
91 | children = (
92 | 97C146EE1CF9000F007C117D /* Runner.app */,
93 | );
94 | name = Products;
95 | sourceTree = "";
96 | };
97 | 97C146F01CF9000F007C117D /* Runner */ = {
98 | isa = PBXGroup;
99 | children = (
100 | 1A49C2B825517AC300421ABB /* Runner.entitlements */,
101 | 1A002F1225502EB6006905AA /* GoogleService-Info.plist */,
102 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
103 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
104 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
105 | 97C147021CF9000F007C117D /* Info.plist */,
106 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
107 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
108 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
109 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
110 | );
111 | path = Runner;
112 | sourceTree = "";
113 | };
114 | CF2974DCF16F8776A7B7DCD0 /* Frameworks */ = {
115 | isa = PBXGroup;
116 | children = (
117 | 036B127D606018CCA6000331 /* Pods_Runner.framework */,
118 | );
119 | name = Frameworks;
120 | sourceTree = "";
121 | };
122 | CF765A2754216E131ABC0089 /* Pods */ = {
123 | isa = PBXGroup;
124 | children = (
125 | 4292FBDDFFC0146FCE7CCAC3 /* Pods-Runner.debug.xcconfig */,
126 | A4368E8CD5C23A3966F43655 /* Pods-Runner.release.xcconfig */,
127 | 9F03826D4E37AC736C4FEF01 /* Pods-Runner.profile.xcconfig */,
128 | );
129 | path = Pods;
130 | sourceTree = "";
131 | };
132 | /* End PBXGroup section */
133 |
134 | /* Begin PBXNativeTarget section */
135 | 97C146ED1CF9000F007C117D /* Runner */ = {
136 | isa = PBXNativeTarget;
137 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
138 | buildPhases = (
139 | 682FB7A730ADEA641680CA2E /* [CP] Check Pods Manifest.lock */,
140 | 9740EEB61CF901F6004384FC /* Run Script */,
141 | 97C146EA1CF9000F007C117D /* Sources */,
142 | 97C146EB1CF9000F007C117D /* Frameworks */,
143 | 97C146EC1CF9000F007C117D /* Resources */,
144 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
145 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
146 | D32E8104304111AC5530D0EC /* [CP] Embed Pods Frameworks */,
147 | 10A48C7CA78000EFB6E3B47A /* [CP] Copy Pods Resources */,
148 | );
149 | buildRules = (
150 | );
151 | dependencies = (
152 | );
153 | name = Runner;
154 | productName = Runner;
155 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
156 | productType = "com.apple.product-type.application";
157 | };
158 | /* End PBXNativeTarget section */
159 |
160 | /* Begin PBXProject section */
161 | 97C146E61CF9000F007C117D /* Project object */ = {
162 | isa = PBXProject;
163 | attributes = {
164 | LastUpgradeCheck = 1020;
165 | ORGANIZATIONNAME = "";
166 | TargetAttributes = {
167 | 97C146ED1CF9000F007C117D = {
168 | CreatedOnToolsVersion = 7.3.1;
169 | LastSwiftMigration = 1100;
170 | };
171 | };
172 | };
173 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
174 | compatibilityVersion = "Xcode 9.3";
175 | developmentRegion = en;
176 | hasScannedForEncodings = 0;
177 | knownRegions = (
178 | en,
179 | Base,
180 | );
181 | mainGroup = 97C146E51CF9000F007C117D;
182 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
183 | projectDirPath = "";
184 | projectRoot = "";
185 | targets = (
186 | 97C146ED1CF9000F007C117D /* Runner */,
187 | );
188 | };
189 | /* End PBXProject section */
190 |
191 | /* Begin PBXResourcesBuildPhase section */
192 | 97C146EC1CF9000F007C117D /* Resources */ = {
193 | isa = PBXResourcesBuildPhase;
194 | buildActionMask = 2147483647;
195 | files = (
196 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
197 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
198 | 1A002F1325502EB6006905AA /* GoogleService-Info.plist in Resources */,
199 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
200 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
201 | );
202 | runOnlyForDeploymentPostprocessing = 0;
203 | };
204 | /* End PBXResourcesBuildPhase section */
205 |
206 | /* Begin PBXShellScriptBuildPhase section */
207 | 10A48C7CA78000EFB6E3B47A /* [CP] Copy Pods Resources */ = {
208 | isa = PBXShellScriptBuildPhase;
209 | buildActionMask = 2147483647;
210 | files = (
211 | );
212 | inputFileListPaths = (
213 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
214 | );
215 | name = "[CP] Copy Pods Resources";
216 | outputFileListPaths = (
217 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
218 | );
219 | runOnlyForDeploymentPostprocessing = 0;
220 | shellPath = /bin/sh;
221 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
222 | showEnvVarsInLog = 0;
223 | };
224 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
225 | isa = PBXShellScriptBuildPhase;
226 | buildActionMask = 2147483647;
227 | files = (
228 | );
229 | inputPaths = (
230 | );
231 | name = "Thin Binary";
232 | outputPaths = (
233 | );
234 | runOnlyForDeploymentPostprocessing = 0;
235 | shellPath = /bin/sh;
236 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
237 | };
238 | 682FB7A730ADEA641680CA2E /* [CP] Check Pods Manifest.lock */ = {
239 | isa = PBXShellScriptBuildPhase;
240 | buildActionMask = 2147483647;
241 | files = (
242 | );
243 | inputFileListPaths = (
244 | );
245 | inputPaths = (
246 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
247 | "${PODS_ROOT}/Manifest.lock",
248 | );
249 | name = "[CP] Check Pods Manifest.lock";
250 | outputFileListPaths = (
251 | );
252 | outputPaths = (
253 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
254 | );
255 | runOnlyForDeploymentPostprocessing = 0;
256 | shellPath = /bin/sh;
257 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
258 | showEnvVarsInLog = 0;
259 | };
260 | 9740EEB61CF901F6004384FC /* Run Script */ = {
261 | isa = PBXShellScriptBuildPhase;
262 | buildActionMask = 2147483647;
263 | files = (
264 | );
265 | inputPaths = (
266 | );
267 | name = "Run Script";
268 | outputPaths = (
269 | );
270 | runOnlyForDeploymentPostprocessing = 0;
271 | shellPath = /bin/sh;
272 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
273 | };
274 | D32E8104304111AC5530D0EC /* [CP] Embed Pods Frameworks */ = {
275 | isa = PBXShellScriptBuildPhase;
276 | buildActionMask = 2147483647;
277 | files = (
278 | );
279 | inputFileListPaths = (
280 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
281 | );
282 | name = "[CP] Embed Pods Frameworks";
283 | outputFileListPaths = (
284 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
285 | );
286 | runOnlyForDeploymentPostprocessing = 0;
287 | shellPath = /bin/sh;
288 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
289 | showEnvVarsInLog = 0;
290 | };
291 | /* End PBXShellScriptBuildPhase section */
292 |
293 | /* Begin PBXSourcesBuildPhase section */
294 | 97C146EA1CF9000F007C117D /* Sources */ = {
295 | isa = PBXSourcesBuildPhase;
296 | buildActionMask = 2147483647;
297 | files = (
298 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
299 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
300 | );
301 | runOnlyForDeploymentPostprocessing = 0;
302 | };
303 | /* End PBXSourcesBuildPhase section */
304 |
305 | /* Begin PBXVariantGroup section */
306 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
307 | isa = PBXVariantGroup;
308 | children = (
309 | 97C146FB1CF9000F007C117D /* Base */,
310 | );
311 | name = Main.storyboard;
312 | sourceTree = "";
313 | };
314 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
315 | isa = PBXVariantGroup;
316 | children = (
317 | 97C147001CF9000F007C117D /* Base */,
318 | );
319 | name = LaunchScreen.storyboard;
320 | sourceTree = "";
321 | };
322 | /* End PBXVariantGroup section */
323 |
324 | /* Begin XCBuildConfiguration section */
325 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
326 | isa = XCBuildConfiguration;
327 | buildSettings = {
328 | ALWAYS_SEARCH_USER_PATHS = NO;
329 | CLANG_ANALYZER_NONNULL = YES;
330 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
331 | CLANG_CXX_LIBRARY = "libc++";
332 | CLANG_ENABLE_MODULES = YES;
333 | CLANG_ENABLE_OBJC_ARC = YES;
334 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
335 | CLANG_WARN_BOOL_CONVERSION = YES;
336 | CLANG_WARN_COMMA = YES;
337 | CLANG_WARN_CONSTANT_CONVERSION = YES;
338 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
339 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
340 | CLANG_WARN_EMPTY_BODY = YES;
341 | CLANG_WARN_ENUM_CONVERSION = YES;
342 | CLANG_WARN_INFINITE_RECURSION = YES;
343 | CLANG_WARN_INT_CONVERSION = YES;
344 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
345 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
346 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
347 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
348 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
349 | CLANG_WARN_STRICT_PROTOTYPES = YES;
350 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
351 | CLANG_WARN_UNREACHABLE_CODE = YES;
352 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
353 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
354 | COPY_PHASE_STRIP = NO;
355 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
356 | ENABLE_NS_ASSERTIONS = NO;
357 | ENABLE_STRICT_OBJC_MSGSEND = YES;
358 | GCC_C_LANGUAGE_STANDARD = gnu99;
359 | GCC_NO_COMMON_BLOCKS = YES;
360 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
361 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
362 | GCC_WARN_UNDECLARED_SELECTOR = YES;
363 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
364 | GCC_WARN_UNUSED_FUNCTION = YES;
365 | GCC_WARN_UNUSED_VARIABLE = YES;
366 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
367 | MTL_ENABLE_DEBUG_INFO = NO;
368 | SDKROOT = iphoneos;
369 | SUPPORTED_PLATFORMS = iphoneos;
370 | TARGETED_DEVICE_FAMILY = "1,2";
371 | VALIDATE_PRODUCT = YES;
372 | };
373 | name = Profile;
374 | };
375 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
376 | isa = XCBuildConfiguration;
377 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
378 | buildSettings = {
379 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
380 | CLANG_ENABLE_MODULES = YES;
381 | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
382 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
383 | DEVELOPMENT_TEAM = AX352BQR6K;
384 | ENABLE_BITCODE = NO;
385 | FRAMEWORK_SEARCH_PATHS = (
386 | "$(inherited)",
387 | "$(PROJECT_DIR)/Flutter",
388 | );
389 | INFOPLIST_FILE = Runner/Info.plist;
390 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
391 | LD_RUNPATH_SEARCH_PATHS = (
392 | "$(inherited)",
393 | "@executable_path/Frameworks",
394 | );
395 | LIBRARY_SEARCH_PATHS = (
396 | "$(inherited)",
397 | "$(PROJECT_DIR)/Flutter",
398 | );
399 | PRODUCT_BUNDLE_IDENTIFIER = com.sonub.fireflutter;
400 | PRODUCT_NAME = "$(TARGET_NAME)";
401 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
402 | SWIFT_VERSION = 5.0;
403 | VERSIONING_SYSTEM = "apple-generic";
404 | };
405 | name = Profile;
406 | };
407 | 97C147031CF9000F007C117D /* Debug */ = {
408 | isa = XCBuildConfiguration;
409 | buildSettings = {
410 | ALWAYS_SEARCH_USER_PATHS = NO;
411 | CLANG_ANALYZER_NONNULL = YES;
412 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
413 | CLANG_CXX_LIBRARY = "libc++";
414 | CLANG_ENABLE_MODULES = YES;
415 | CLANG_ENABLE_OBJC_ARC = YES;
416 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
417 | CLANG_WARN_BOOL_CONVERSION = YES;
418 | CLANG_WARN_COMMA = YES;
419 | CLANG_WARN_CONSTANT_CONVERSION = YES;
420 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
421 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
422 | CLANG_WARN_EMPTY_BODY = YES;
423 | CLANG_WARN_ENUM_CONVERSION = YES;
424 | CLANG_WARN_INFINITE_RECURSION = YES;
425 | CLANG_WARN_INT_CONVERSION = YES;
426 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
427 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
428 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
429 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
430 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
431 | CLANG_WARN_STRICT_PROTOTYPES = YES;
432 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
433 | CLANG_WARN_UNREACHABLE_CODE = YES;
434 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
435 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
436 | COPY_PHASE_STRIP = NO;
437 | DEBUG_INFORMATION_FORMAT = dwarf;
438 | ENABLE_STRICT_OBJC_MSGSEND = YES;
439 | ENABLE_TESTABILITY = YES;
440 | GCC_C_LANGUAGE_STANDARD = gnu99;
441 | GCC_DYNAMIC_NO_PIC = NO;
442 | GCC_NO_COMMON_BLOCKS = YES;
443 | GCC_OPTIMIZATION_LEVEL = 0;
444 | GCC_PREPROCESSOR_DEFINITIONS = (
445 | "DEBUG=1",
446 | "$(inherited)",
447 | );
448 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
449 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
450 | GCC_WARN_UNDECLARED_SELECTOR = YES;
451 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
452 | GCC_WARN_UNUSED_FUNCTION = YES;
453 | GCC_WARN_UNUSED_VARIABLE = YES;
454 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
455 | MTL_ENABLE_DEBUG_INFO = YES;
456 | ONLY_ACTIVE_ARCH = YES;
457 | SDKROOT = iphoneos;
458 | TARGETED_DEVICE_FAMILY = "1,2";
459 | };
460 | name = Debug;
461 | };
462 | 97C147041CF9000F007C117D /* Release */ = {
463 | isa = XCBuildConfiguration;
464 | buildSettings = {
465 | ALWAYS_SEARCH_USER_PATHS = NO;
466 | CLANG_ANALYZER_NONNULL = YES;
467 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
468 | CLANG_CXX_LIBRARY = "libc++";
469 | CLANG_ENABLE_MODULES = YES;
470 | CLANG_ENABLE_OBJC_ARC = YES;
471 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
472 | CLANG_WARN_BOOL_CONVERSION = YES;
473 | CLANG_WARN_COMMA = YES;
474 | CLANG_WARN_CONSTANT_CONVERSION = YES;
475 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
476 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
477 | CLANG_WARN_EMPTY_BODY = YES;
478 | CLANG_WARN_ENUM_CONVERSION = YES;
479 | CLANG_WARN_INFINITE_RECURSION = YES;
480 | CLANG_WARN_INT_CONVERSION = YES;
481 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
482 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
483 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
484 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
485 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
486 | CLANG_WARN_STRICT_PROTOTYPES = YES;
487 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
488 | CLANG_WARN_UNREACHABLE_CODE = YES;
489 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
490 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
491 | COPY_PHASE_STRIP = NO;
492 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
493 | ENABLE_NS_ASSERTIONS = NO;
494 | ENABLE_STRICT_OBJC_MSGSEND = YES;
495 | GCC_C_LANGUAGE_STANDARD = gnu99;
496 | GCC_NO_COMMON_BLOCKS = YES;
497 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
498 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
499 | GCC_WARN_UNDECLARED_SELECTOR = YES;
500 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
501 | GCC_WARN_UNUSED_FUNCTION = YES;
502 | GCC_WARN_UNUSED_VARIABLE = YES;
503 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
504 | MTL_ENABLE_DEBUG_INFO = NO;
505 | SDKROOT = iphoneos;
506 | SUPPORTED_PLATFORMS = iphoneos;
507 | SWIFT_COMPILATION_MODE = wholemodule;
508 | SWIFT_OPTIMIZATION_LEVEL = "-O";
509 | TARGETED_DEVICE_FAMILY = "1,2";
510 | VALIDATE_PRODUCT = YES;
511 | };
512 | name = Release;
513 | };
514 | 97C147061CF9000F007C117D /* Debug */ = {
515 | isa = XCBuildConfiguration;
516 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
517 | buildSettings = {
518 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
519 | CLANG_ENABLE_MODULES = YES;
520 | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
521 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
522 | DEVELOPMENT_TEAM = AX352BQR6K;
523 | ENABLE_BITCODE = NO;
524 | FRAMEWORK_SEARCH_PATHS = (
525 | "$(inherited)",
526 | "$(PROJECT_DIR)/Flutter",
527 | );
528 | INFOPLIST_FILE = Runner/Info.plist;
529 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
530 | LD_RUNPATH_SEARCH_PATHS = (
531 | "$(inherited)",
532 | "@executable_path/Frameworks",
533 | );
534 | LIBRARY_SEARCH_PATHS = (
535 | "$(inherited)",
536 | "$(PROJECT_DIR)/Flutter",
537 | );
538 | PRODUCT_BUNDLE_IDENTIFIER = com.sonub.fireflutter;
539 | PRODUCT_NAME = "$(TARGET_NAME)";
540 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
541 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
542 | SWIFT_VERSION = 5.0;
543 | VERSIONING_SYSTEM = "apple-generic";
544 | };
545 | name = Debug;
546 | };
547 | 97C147071CF9000F007C117D /* Release */ = {
548 | isa = XCBuildConfiguration;
549 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
550 | buildSettings = {
551 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
552 | CLANG_ENABLE_MODULES = YES;
553 | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
554 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
555 | DEVELOPMENT_TEAM = AX352BQR6K;
556 | ENABLE_BITCODE = NO;
557 | FRAMEWORK_SEARCH_PATHS = (
558 | "$(inherited)",
559 | "$(PROJECT_DIR)/Flutter",
560 | );
561 | INFOPLIST_FILE = Runner/Info.plist;
562 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
563 | LD_RUNPATH_SEARCH_PATHS = (
564 | "$(inherited)",
565 | "@executable_path/Frameworks",
566 | );
567 | LIBRARY_SEARCH_PATHS = (
568 | "$(inherited)",
569 | "$(PROJECT_DIR)/Flutter",
570 | );
571 | PRODUCT_BUNDLE_IDENTIFIER = com.sonub.fireflutter;
572 | PRODUCT_NAME = "$(TARGET_NAME)";
573 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
574 | SWIFT_VERSION = 5.0;
575 | VERSIONING_SYSTEM = "apple-generic";
576 | };
577 | name = Release;
578 | };
579 | /* End XCBuildConfiguration section */
580 |
581 | /* Begin XCConfigurationList section */
582 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
583 | isa = XCConfigurationList;
584 | buildConfigurations = (
585 | 97C147031CF9000F007C117D /* Debug */,
586 | 97C147041CF9000F007C117D /* Release */,
587 | 249021D3217E4FDB00AE95B9 /* Profile */,
588 | );
589 | defaultConfigurationIsVisible = 0;
590 | defaultConfigurationName = Release;
591 | };
592 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
593 | isa = XCConfigurationList;
594 | buildConfigurations = (
595 | 97C147061CF9000F007C117D /* Debug */,
596 | 97C147071CF9000F007C117D /* Release */,
597 | 249021D4217E4FDB00AE95B9 /* Profile */,
598 | );
599 | defaultConfigurationIsVisible = 0;
600 | defaultConfigurationName = Release;
601 | };
602 | /* End XCConfigurationList section */
603 | };
604 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
605 | }
606 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
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 |
--------------------------------------------------------------------------------
/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/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/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/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/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/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/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/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/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/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/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/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/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/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/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/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/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/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/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/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/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/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/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/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/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/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/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.
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/GoogleService-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CLIENT_ID
6 | 389649476574-3pp2tstq9l5k8ecotn228v6b0gl905vp.apps.googleusercontent.com
7 | REVERSED_CLIENT_ID
8 | com.googleusercontent.apps.389649476574-3pp2tstq9l5k8ecotn228v6b0gl905vp
9 | API_KEY
10 | AIzaSyCe2BoolOEIpBvLGexp9QTyF7qStRE_cR0
11 | GCM_SENDER_ID
12 | 389649476574
13 | PLIST_VERSION
14 | 1
15 | BUNDLE_ID
16 | com.sonub.fireflutter
17 | PROJECT_ID
18 | fireflutter-test
19 | STORAGE_BUCKET
20 | fireflutter-test.appspot.com
21 | IS_ADS_ENABLED
22 |
23 | IS_ANALYTICS_ENABLED
24 |
25 | IS_APPINVITE_ENABLED
26 |
27 | IS_GCM_ENABLED
28 |
29 | IS_SIGNIN_ENABLED
30 |
31 | GOOGLE_APP_ID
32 | 1:389649476574:ios:23cd30a938db5c2156cb4f
33 | DATABASE_URL
34 | https://fireflutter-test.firebaseio.com
35 |
36 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleLocalizations
14 |
15 | en
16 | ch
17 | ja
18 | ko
19 |
20 | CFBundleName
21 | fireflutter_sample_app
22 | CFBundlePackageType
23 | APPL
24 | CFBundleShortVersionString
25 | $(FLUTTER_BUILD_NAME)
26 | CFBundleSignature
27 | ????
28 | CFBundleURLTypes
29 |
30 |
31 | CFBundleURLSchemes
32 |
33 | fb2760886707561630
34 |
35 |
36 |
37 | CFBundleTypeRole
38 | Editor
39 | CFBundleURLSchemes
40 |
41 | com.googleusercontent.apps.389649476574-3pp2tstq9l5k8ecotn228v6b0gl905vp
42 |
43 |
44 |
45 | CFBundleVersion
46 | $(FLUTTER_BUILD_NUMBER)
47 | FacebookAppID
48 | 2760886707561630
49 | FacebookDisplayName
50 | Name FireFlutter Test
51 | LSApplicationQueriesSchemes
52 |
53 | fbapi
54 | fb-messenger-share-api
55 | fbauth2
56 | fbshareextension
57 |
58 | LSRequiresIPhoneOS
59 |
60 | NSCameraUsageDescription
61 | $(EXECUTABLE_NAME) need access to Camera.
62 | NSMicrophoneUsageDescription
63 | $(EXECUTABLE_NAME) need access to Microphone.
64 | NSPhotoLibraryUsageDescription
65 | $(EXECUTABLE_NAME) need access to Photo Library.
66 | UILaunchStoryboardName
67 | LaunchScreen
68 | UIMainStoryboardFile
69 | Main
70 | UISupportedInterfaceOrientations
71 |
72 | UIInterfaceOrientationPortrait
73 | UIInterfaceOrientationLandscapeLeft
74 | UIInterfaceOrientationLandscapeRight
75 |
76 | UISupportedInterfaceOrientations~ipad
77 |
78 | UIInterfaceOrientationPortrait
79 | UIInterfaceOrientationPortraitUpsideDown
80 | UIInterfaceOrientationLandscapeLeft
81 | UIInterfaceOrientationLandscapeRight
82 |
83 | UIViewControllerBasedStatusBarAppearance
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/ios/Runner/Runner.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.developer.applesignin
6 |
7 | Default
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/keystore.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thruthesky/fireflutter_sample_app/64e7ab50ca775629fd2d4f6ad5f75d5691e8d3d2/keystore.key
--------------------------------------------------------------------------------
/lib/global_variables.dart:
--------------------------------------------------------------------------------
1 | import 'package:fireflutter/fireflutter.dart';
2 |
3 | FireFlutter ff = FireFlutter();
4 |
--------------------------------------------------------------------------------
/lib/keys.dart:
--------------------------------------------------------------------------------
1 | class Keys {
2 | static const homeScreen = 'home_screen';
3 | static const hPleaseLogin = 'home_screen_please_login';
4 | static const hLogoutButton = 'home_screen_logout_buton';
5 | static const hLoginButton = 'home_screen_login_buton';
6 | static const hInfo = 'home_screen_info';
7 | static const rButton = 'register_button';
8 | static const rsButton = 'register_submit_button';
9 | static const riEmail = 'register_input_email';
10 | static const riPassword = 'register_input_password';
11 | static const riDisplayName = 'register_input_displayname';
12 | static const riColor = 'register_input_color';
13 | static const hEmail = 'home_screen_email';
14 | static const hColor = 'home_screen_color';
15 | static const lfEmail = 'login_form_email';
16 | static const lfPassword = 'login_form_password';
17 | static const lfSubmitButton = 'login_form_submit_button';
18 | static const hProfileButotn = 'home_screen_profile_button';
19 | static const pfSubmitButton = 'profile_form_submit_button';
20 | static const pfDisplayName = 'profile_form_display_name';
21 | static const pfColor = 'profile_form_color';
22 | }
23 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:fireflutter/fireflutter.dart';
4 | import 'package:fireflutter_sample_app/screens/admin/admin.screen.dart';
5 | import 'package:fireflutter_sample_app/screens/admin/admin.category.screen.dart';
6 | import 'package:fireflutter_sample_app/screens/forum/post.edit.screen.dart';
7 | import 'package:fireflutter_sample_app/screens/forum/post.list.screen.dart';
8 | import 'package:fireflutter_sample_app/screens/home/home.screen.dart';
9 | import 'package:fireflutter_sample_app/screens/login/login.screen.dart';
10 | import 'package:fireflutter_sample_app/screens/phone_auth/phone_auth.screen.dart';
11 | import 'package:fireflutter_sample_app/screens/phone_auth/phone_auth_verification_code.screen.dart';
12 | import 'package:fireflutter_sample_app/screens/profile/profile.screen.dart';
13 | import 'package:fireflutter_sample_app/screens/push-notification/push-notification.screen.dart';
14 | import 'package:fireflutter_sample_app/screens/register/register.screen.dart';
15 | import 'package:fireflutter_sample_app/screens/search/search.screen.dart';
16 | import 'package:fireflutter_sample_app/screens/settings/settings.screen.dart';
17 | import 'package:fireflutter_sample_app/translations.dart';
18 | import 'package:flutter/material.dart';
19 | import 'package:get/get.dart';
20 | import './global_variables.dart';
21 |
22 | void main() async {
23 | WidgetsFlutterBinding.ensureInitialized();
24 | await ff.init(
25 | settings: {
26 | 'app': {
27 | 'default-language': 'ko',
28 | 'verify-after-register': false,
29 | 'verify-after-login': false,
30 | 'force-verification': false,
31 | 'block-non-verified-users-to-create': false,
32 | 'ALGOLIA_APP_ID': "W42X6RIXO5",
33 | 'ALGOLIA_SEARCH_KEY': "710ce6c481caf890163ba0c24573130f",
34 | 'ALGOLIA_INDEX_NAME': "Dev"
35 | },
36 | },
37 | translations: translations,
38 | enableNotification: true,
39 | firebaseServerToken:
40 | 'AAAAWrjrK94:APA91bGJuMd80xlpz1m8W61PxCS_2Ir_5y4mUcjPMUlNi-wGGaFoXQL9XiUTjBSv8fCSBBWa9-GTsuFNPWfrCF9TFOCmeJgzxtXfuS5EgH1NWEuEmlerbFAz-XIa2DYEpyQWkWwhFQJa',
41 | );
42 | runApp(MainApp());
43 | }
44 |
45 | class MainApp extends StatefulWidget {
46 | @override
47 | _MainAppState createState() => _MainAppState();
48 | }
49 |
50 | class _MainAppState extends State {
51 | @override
52 | void initState() {
53 | super.initState();
54 | ff.translationsChange.listen((x) => setState(() => updateTranslations(x)));
55 | ff.userChange.listen((x) {
56 | setState(() {
57 | Get.updateLocale(Locale(ff.userLanguage));
58 | });
59 | });
60 | ff.settingsChange.listen((settings) {
61 | setState(() {});
62 | });
63 | Timer(Duration(milliseconds: 200), () {
64 | // Get.toNamed(
65 | // 'forum-list',
66 | // arguments: {'category': 'qna'},
67 | // );
68 | // Get.toNamed('phone-auth');
69 |
70 | // () async {
71 | // await ff.login(email: 'user@gmail.com', password: '12345a');
72 | // print(ff.user.uid);
73 | // print(ff.user.email);
74 | // }();
75 | // Get.toNamed('settings');
76 | });
77 |
78 | ff.notification.listen((x) {
79 | Map notification = x['notification'];
80 | Map data = x['data'];
81 | NotificationType type = x['type'];
82 | // print('NotificationType: $type');
83 | // print('notification: $notification');
84 | // print('data: $data');
85 |
86 | /// Ignore message from myself.
87 | if (data['senderUid'] == ff.user.uid) {
88 | return;
89 | }
90 | if (type == NotificationType.onMessage) {
91 | Get.snackbar(
92 | notification['title'].toString(),
93 | notification['body'].toString(),
94 | onTap: (_) {
95 | if (data != null && data['screen'] != null) {
96 | Get.toNamed(data['screen'], arguments: {'id': data['id'] ?? ''});
97 | }
98 | },
99 | mainButton: (data != null && data['screen'] != null)
100 | ? FlatButton(
101 | child: Text('Open'),
102 | onPressed: () {
103 | Get.toNamed(data['screen'],
104 | arguments: {'id': data['id'] ?? ''});
105 | },
106 | )
107 | : Container(),
108 | );
109 | } else {
110 | /// App will come here when the user open the app by tapping a push notification on the system tray.
111 | if (data != null && data['screen'] != null) {
112 | Get.toNamed(data['screen'],
113 | arguments: {'id': data['id'] ?? '', 'data': data});
114 | }
115 | }
116 | });
117 | }
118 |
119 | @override
120 | Widget build(BuildContext context) {
121 | return GetMaterialApp(
122 | initialRoute: 'home',
123 | locale: Locale(ff.userLanguage),
124 | translations: AppTranslations(),
125 | getPages: [
126 | GetPage(name: 'home', page: () => HomeScreen()),
127 | GetPage(name: 'register', page: () => RegisterScreen()),
128 | GetPage(name: 'login', page: () => LoginScreen()),
129 | GetPage(name: 'profile', page: () => ProfileScreen()),
130 | GetPage(name: 'admin', page: () => AdminScreen()),
131 | GetPage(name: 'admin-category', page: () => AdminCategoryScreen()),
132 | GetPage(name: 'forum-edit', page: () => ForumEditScreen()),
133 | GetPage(name: 'forum-list', page: () => ForumListScreen()),
134 | GetPage(name: 'phone-auth', page: () => PhoneAuthScreen()),
135 | GetPage(
136 | name: 'phone-auth-code-verification',
137 | page: () => PhoneAuthCodeVerificationScreen()),
138 | GetPage(name: 'push-notification', page: () => PushNotification()),
139 | GetPage(name: 'settings', page: () => SettingsScreen()),
140 | GetPage(name: 'search', page: () => SearchScreen()),
141 | ],
142 | routingCallback: (routing) {
143 | if (ff.loggedIn) {
144 | if (ff.user.phoneNumber.isNullOrBlank &&
145 | ff.appSetting('force-verification') == true) {
146 | if (routing.current != 'home') {
147 | WidgetsBinding.instance
148 | .addPostFrameCallback((_) => Get.offNamed('phone-auth'));
149 | }
150 | }
151 | }
152 | },
153 | );
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/lib/screens/admin/admin.category.screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:cloud_firestore/cloud_firestore.dart';
2 | import 'package:fireflutter_sample_app/global_variables.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:get/get.dart';
5 |
6 | enum Mode { create, update, delete }
7 |
8 | class AdminCategoryScreen extends StatefulWidget {
9 | @override
10 | _AdminCategoryScreenState createState() => _AdminCategoryScreenState();
11 | }
12 |
13 | class _AdminCategoryScreenState extends State {
14 | final idController = TextEditingController();
15 | final titleController = TextEditingController();
16 | final descriptionController = TextEditingController();
17 |
18 | final db = FirebaseFirestore.instance;
19 | CollectionReference get categories => db.collection('categories');
20 |
21 | Mode mode = Mode.create;
22 |
23 | reset() {
24 | setState(() {
25 | idController.text = '';
26 | mode = Mode.create;
27 | titleController.text = '';
28 | descriptionController.text = '';
29 | });
30 | }
31 |
32 | @override
33 | Widget build(BuildContext context) {
34 | return Scaffold(
35 | appBar: AppBar(
36 | title: Text('Forum Category'),
37 | ),
38 | body: Container(
39 | padding: EdgeInsets.all(16),
40 | child: ff.isAdmin
41 | ? Container(
42 | child: Column(
43 | children: [
44 | TextFormField(
45 | controller: idController,
46 | decoration: InputDecoration(labelText: "Category ID"),
47 | enabled: mode == Mode.create,
48 | ),
49 | TextFormField(
50 | controller: titleController,
51 | decoration: InputDecoration(labelText: "Title"),
52 | ),
53 | TextFormField(
54 | controller: descriptionController,
55 | decoration: InputDecoration(labelText: "Description"),
56 | ),
57 | Row(
58 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
59 | children: [
60 | RaisedButton(
61 | onPressed: reset,
62 | child: Text('Reset'),
63 | ),
64 | RaisedButton(
65 | onPressed: () async {
66 | String id = idController.text;
67 | String title = titleController.text;
68 | String description = descriptionController.text;
69 | try {
70 | if (mode == Mode.create) {
71 | DocumentSnapshot doc =
72 | await categories.doc(id).get();
73 | if (doc.exists) {
74 | return Get.snackbar(
75 | 'Error', 'Category exists');
76 | }
77 | }
78 | await categories.doc(id).set({
79 | 'id': id,
80 | 'title': title,
81 | 'description': description,
82 | }, SetOptions(merge: true));
83 | reset();
84 | } catch (e) {
85 | Get.snackbar('Error', e.toString());
86 | }
87 | },
88 | child: Text('Submit'),
89 | )
90 | ],
91 | ),
92 | StreamBuilder(
93 | stream: categories.snapshots(),
94 | builder: (c, AsyncSnapshot snapshot) {
95 | if (snapshot.hasError) {
96 | return Text('Something went wrong');
97 | }
98 |
99 | if (snapshot.connectionState ==
100 | ConnectionState.waiting) {
101 | return SizedBox.shrink();
102 | }
103 |
104 | return ListView.builder(
105 | shrinkWrap: true,
106 | itemCount: snapshot.data.docs.length,
107 | itemBuilder: (cc, i) {
108 | QueryDocumentSnapshot doc =
109 | snapshot.data.docs.elementAt(i);
110 | final Map data = doc.data();
111 |
112 | return ListTile(
113 | title: Text(data['id'] + ' : ' + data['title']),
114 | subtitle: Text(data['description']),
115 | trailing: PopupMenuButton(
116 | icon: Icon(Icons.more_vert),
117 | onSelected: (Mode result) {
118 | if (result == Mode.update) {
119 | mode = Mode.update;
120 | idController.text = data['id'];
121 | titleController.text = data['title'];
122 | descriptionController.text =
123 | data['description'];
124 | } else if (result == Mode.delete) {
125 | categories.doc(data['id']).delete();
126 | }
127 | },
128 | itemBuilder: (BuildContext context) =>
129 | >[
130 | const PopupMenuItem(
131 | value: Mode.update,
132 | child: Text('Update'),
133 | ),
134 | const PopupMenuItem(
135 | value: Mode.delete,
136 | child: Text('Delete'),
137 | ),
138 | ],
139 | ),
140 | );
141 | },
142 | );
143 | },
144 | ),
145 | ],
146 | ),
147 | )
148 | : Text('You are not admin!'),
149 | ),
150 | );
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/lib/screens/admin/admin.screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:get/get.dart';
3 |
4 | class AdminScreen extends StatefulWidget {
5 | @override
6 | _AdminScreenState createState() => _AdminScreenState();
7 | }
8 |
9 | class _AdminScreenState extends State {
10 | @override
11 | Widget build(BuildContext context) {
12 | return Scaffold(
13 | appBar: AppBar(
14 | title: Text('Admin Screen'),
15 | ),
16 | body: Column(
17 | children: [
18 | RaisedButton(
19 | onPressed: () => Get.toNamed('admin-category'),
20 | child: Text('Forum Category'),
21 | ),
22 | ],
23 | ),
24 | );
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lib/screens/forum/comment.dart:
--------------------------------------------------------------------------------
1 | import 'package:fireflutter/fireflutter.dart';
2 | import 'package:fireflutter_sample_app/global_variables.dart';
3 | import 'package:fireflutter_sample_app/screens/forum/comment.form.dart';
4 | import 'package:fireflutter_sample_app/screens/forum/display_photos.dart';
5 | import 'package:flutter/material.dart';
6 | import 'package:get/route_manager.dart';
7 |
8 | class Comment extends StatefulWidget {
9 | const Comment({
10 | Key key,
11 | @required this.post,
12 | this.index,
13 | }) : super(key: key);
14 |
15 | final Map post;
16 | final int index;
17 |
18 | @override
19 | _CommentState createState() => _CommentState();
20 | }
21 |
22 | class _CommentState extends State {
23 | bool edit = false;
24 | Map comment;
25 | @override
26 | Widget build(BuildContext context) {
27 | comment = widget.post['comments'][widget.index];
28 | return Column(
29 | crossAxisAlignment: CrossAxisAlignment.start,
30 | children: [
31 | Text(
32 | comment['id'],
33 | style: TextStyle(
34 | fontSize: 10,
35 | ),
36 | ),
37 | edit
38 | ? CommentForm(
39 | post: widget.post,
40 | comment: comment,
41 | onCancel: () => setState(() => edit = false),
42 | onSuccess: () => setState(() => edit = false),
43 | )
44 | : Column(
45 | children: [
46 | Container(
47 | margin:
48 | EdgeInsets.only(top: 16, left: comment['depth'] * 32.0),
49 | padding: EdgeInsets.all(16),
50 | width: double.infinity,
51 | color: Colors.grey[200],
52 | child: Text(comment['content'],
53 | style: TextStyle(fontSize: 16)),
54 | ),
55 | DisplayPhotos(files: comment['files']),
56 | Row(
57 | children: [
58 | TextButton(
59 | onPressed: () => setState(() => edit = true),
60 | child: Text('Edit'),
61 | ),
62 | TextButton(
63 | onPressed: () async {
64 | try {
65 | await ff.deleteComment(
66 | widget.post['id'],
67 | comment['id'],
68 | );
69 | } catch (e) {
70 | Get.snackbar('Error', e.toString());
71 | }
72 | },
73 | child: Text('Delete'),
74 | ),
75 | TextButton(
76 | onPressed: () async {
77 | try {
78 | await ff.vote(
79 | postId: widget.post['id'],
80 | commentId: comment['id'],
81 | choice: VoteChoice.like,
82 | );
83 | } catch (e) {
84 | Get.snackbar('Error', e.toString());
85 | }
86 | },
87 | child: Text('Like ${comment['likes'] ?? ''}'),
88 | ),
89 | TextButton(
90 | onPressed: () async {
91 | try {
92 | await ff.vote(
93 | postId: widget.post['id'],
94 | commentId: comment['id'],
95 | choice: VoteChoice.dislike,
96 | );
97 | } catch (e) {
98 | Get.snackbar('Error', e.toString());
99 | }
100 | },
101 | child: Text('Dislike ${comment['dislikes'] ?? ''}'),
102 | ),
103 | ],
104 | ),
105 | CommentForm(
106 | post: widget.post,
107 | parentIndex: widget.index,
108 | )
109 | ],
110 | ),
111 | ],
112 | );
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/lib/screens/forum/comment.form.dart:
--------------------------------------------------------------------------------
1 | import 'package:fireflutter_sample_app/global_variables.dart';
2 | import 'package:fireflutter_sample_app/screens/forum/edit_photos.dart';
3 | import 'package:fireflutter_sample_app/screens/forum/photo_upload.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:get/get.dart';
6 |
7 | class CommentForm extends StatefulWidget {
8 | const CommentForm({
9 | Key key,
10 | @required this.post,
11 | this.comment,
12 | this.parentIndex,
13 | this.onCancel,
14 | this.onSuccess,
15 | }) : super(key: key);
16 |
17 | /// the post that this comments belongs to.
18 | final Map post;
19 |
20 | /// comment to edit.
21 | ///
22 | /// If it is not edit, then it must be null.
23 | final Map comment;
24 |
25 | /// [parentIndex] is the position of the comment that the new comment is
26 | /// going to be attached to in post.comments array
27 | ///
28 | final int parentIndex;
29 |
30 | final Function onCancel;
31 | final Function onSuccess;
32 |
33 | @override
34 | _CommentFormState createState() => _CommentFormState();
35 | }
36 |
37 | class _CommentFormState extends State {
38 | final contentController = TextEditingController();
39 |
40 | List files = [];
41 | double uploadProgress = 0;
42 | @override
43 | initState() {
44 | if (widget.comment != null) {
45 | files = widget.comment['files'] ?? [];
46 | contentController.text = widget.comment['content'];
47 | }
48 | super.initState();
49 | }
50 |
51 | @override
52 | Widget build(BuildContext context) {
53 | return Column(
54 | children: [
55 | Row(
56 | children: [
57 | PhotoUpload(
58 | files: files,
59 | onProgress: (p) => setState(() => uploadProgress = p),
60 | ),
61 | Expanded(
62 | child: TextFormField(controller: contentController),
63 | ),
64 | ],
65 | ),
66 | if (uploadProgress > 0)
67 | LinearProgressIndicator(
68 | value: uploadProgress,
69 | ),
70 | EditPotos(
71 | files: files,
72 | ),
73 | Row(
74 | mainAxisAlignment: MainAxisAlignment.end,
75 | children: [
76 | if (widget.onCancel != null)
77 | TextButton(onPressed: widget.onCancel, child: Text('Cancel')),
78 | RaisedButton(
79 | onPressed: () async {
80 | if (ff.user.phoneNumber.isNullOrBlank &&
81 | ff.appSetting('block-non-verified-users-to-create') ==
82 | true) {
83 | Get.defaultDialog(
84 | middleText: 'Please verify your phone number first!',
85 | textConfirm: 'Ok',
86 | confirmTextColor: Colors.white,
87 | onConfirm: () => Get.back(),
88 | );
89 | return;
90 | }
91 | final data = {
92 | 'content': contentController.text,
93 | 'files': files
94 | };
95 | if (widget.comment != null) {
96 | data['id'] = widget.comment['id'];
97 | }
98 | try {
99 | await ff.editComment(data, widget.post,
100 | parentIndex: widget.parentIndex);
101 | contentController.text = '';
102 | files = [];
103 | if (widget.onSuccess != null) widget.onSuccess();
104 | } catch (e) {
105 | Get.snackbar('Error', e.toString());
106 | }
107 | },
108 | child: Text('Submit'),
109 | ),
110 | ],
111 | )
112 | ],
113 | );
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/lib/screens/forum/display_photos.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class DisplayPhotos extends StatelessWidget {
4 | DisplayPhotos({
5 | Key key,
6 | @required this.files,
7 | }) : super(key: key);
8 |
9 | final List files;
10 | @override
11 | Widget build(BuildContext context) {
12 | /// Display uploaded images.
13 | if (files == null) {
14 | return Container();
15 | } else {
16 | return Column(
17 | children: [
18 | for (String url in files) Image.network(url),
19 | ],
20 | );
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/screens/forum/edit_photos.dart:
--------------------------------------------------------------------------------
1 | import 'package:fireflutter_sample_app/global_variables.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:get/get.dart';
4 |
5 | class EditPotos extends StatefulWidget {
6 | EditPotos({this.files});
7 | final List files;
8 | @override
9 | _EditPotosState createState() => _EditPotosState();
10 | }
11 |
12 | class _EditPotosState extends State {
13 | @override
14 | Widget build(BuildContext context) {
15 | return Container(
16 | child: Wrap(
17 | children: [
18 | for (String url in widget.files)
19 | Stack(
20 | children: [
21 | SizedBox(
22 | child: Image.network(url),
23 | width: 100,
24 | height: 100,
25 | ),
26 | MaterialButton(
27 | onPressed: () async {
28 | try {
29 | await ff.deleteFile(url);
30 | setState(() => widget.files.remove(url));
31 | } catch (e) {
32 | Get.snackbar('Error', e.toString());
33 | }
34 | },
35 | color: Colors.blue,
36 | textColor: Colors.white,
37 | child: Icon(
38 | Icons.delete,
39 | size: 24,
40 | ),
41 | padding: EdgeInsets.all(4.0),
42 | shape: CircleBorder(),
43 | ),
44 | ],
45 | ),
46 | ],
47 | ),
48 | );
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/lib/screens/forum/photo_upload.dart:
--------------------------------------------------------------------------------
1 | import 'package:fireflutter_sample_app/global_variables.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:get/get.dart';
4 | import 'package:image_picker/image_picker.dart';
5 |
6 | class PhotoUpload extends StatelessWidget {
7 | PhotoUpload({@required this.files, @required this.onProgress});
8 | final List files;
9 | final Function onProgress;
10 | Widget build(BuildContext context) {
11 | return IconButton(
12 | icon: Icon(Icons.camera_alt),
13 | onPressed: () async {
14 | /// Get source of photo
15 | ImageSource source = await showDialog(
16 | context: context,
17 | builder: (_) => AlertDialog(
18 | title: Text('Choose Camera or Gallery'),
19 | content: Column(
20 | mainAxisSize: MainAxisSize.min,
21 | children: [
22 | TextButton(
23 | onPressed: () => Get.back(result: ImageSource.camera),
24 | child: Text('Camera'),
25 | ),
26 | TextButton(
27 | onPressed: () => Get.back(result: ImageSource.gallery),
28 | child: Text('Gallery'),
29 | ),
30 | ],
31 | ),
32 | ),
33 | );
34 |
35 | if (source == null) return null;
36 |
37 | /// Upload photo
38 | try {
39 | final url = await ff.uploadFile(
40 | folder: 'forum-photos',
41 | source: source,
42 | progress: onProgress,
43 | );
44 |
45 | files.add(url);
46 | onProgress(0.0);
47 | } catch (e) {
48 | Get.snackbar('Error', e.toString());
49 | }
50 | },
51 | );
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/lib/screens/forum/post.edit.screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:fireflutter_sample_app/global_variables.dart';
2 | import 'package:fireflutter_sample_app/screens/forum/edit_photos.dart';
3 | import 'package:fireflutter_sample_app/screens/forum/photo_upload.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:get/get.dart';
6 |
7 | class ForumEditScreen extends StatefulWidget {
8 | @override
9 | _ForumEditScreenState createState() => _ForumEditScreenState();
10 | }
11 |
12 | class _ForumEditScreenState extends State {
13 | /// Text box controllers
14 | final titleController = TextEditingController();
15 | final contentController = TextEditingController();
16 |
17 | /// Category ID
18 | String category;
19 |
20 | /// Post to edit
21 | Map post;
22 |
23 | /// Container for uploaded files
24 | List files = [];
25 |
26 | /// Progress bar percentage
27 | double uploadProgress = 0;
28 |
29 | @override
30 | void initState() {
31 | super.initState();
32 |
33 | /// If `category` is passed, then it is post create.
34 | if (Get.arguments['category'] != null) {
35 | category = Get.arguments['category'];
36 | } else {
37 | /// Or it's post update.
38 | post = Get.arguments['post'];
39 | titleController.text = post['title'];
40 | contentController.text = post['content'];
41 | category = post['category'];
42 | files = post['files'] ?? [];
43 | }
44 | }
45 |
46 | @override
47 | void dispose() {
48 | titleController.dispose();
49 | contentController.dispose();
50 | super.dispose();
51 | }
52 |
53 | bool get formInvalid => false;
54 |
55 | @override
56 | Widget build(BuildContext context) {
57 | return Scaffold(
58 | appBar: AppBar(
59 | title: Text('Forum Edit'),
60 | ),
61 | body: Column(
62 | children: [
63 | TextFormField(
64 | controller: titleController,
65 | decoration: InputDecoration(hintText: 'title'),
66 | ),
67 | TextFormField(
68 | controller: contentController,
69 | decoration: InputDecoration(hintText: 'content'),
70 | ),
71 | Row(
72 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
73 | children: [
74 | PhotoUpload(
75 | files: files,
76 | onProgress: (p) => setState(() => uploadProgress = p),
77 | ),
78 | RaisedButton(
79 | onPressed: () async {
80 | if (formInvalid) {
81 | return Get.snackbar('title', 'message');
82 | }
83 | try {
84 | await ff.editPost({
85 | 'id': post == null ? null : post['id'],
86 | 'category': category,
87 | 'title': titleController.text,
88 | 'content': contentController.text,
89 | 'uid': ff.user.uid,
90 | 'files': files,
91 | });
92 |
93 | /// Should go back since new post will be updated in real time.
94 | Get.back();
95 | } catch (e) {
96 | Get.snackbar('Error', e.toString());
97 | }
98 | },
99 | child: Text('submit'.tr),
100 | ),
101 | ],
102 | ),
103 | if (uploadProgress > 0)
104 | LinearProgressIndicator(
105 | value: uploadProgress,
106 | ),
107 | EditPotos(
108 | files: files,
109 | ),
110 | ],
111 | ),
112 | );
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/lib/screens/forum/post.list.screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:fireflutter/fireflutter.dart';
2 | import 'package:fireflutter_sample_app/global_variables.dart';
3 | import 'package:fireflutter_sample_app/screens/forum/comment.dart';
4 | import 'package:fireflutter_sample_app/screens/forum/comment.form.dart';
5 | import 'package:fireflutter_sample_app/screens/forum/display_photos.dart';
6 | import 'package:flutter/material.dart';
7 | import 'package:font_awesome_flutter/font_awesome_flutter.dart';
8 | import 'package:get/get.dart';
9 | import 'package:cloud_firestore/cloud_firestore.dart';
10 |
11 | class ForumListScreen extends StatefulWidget {
12 | @override
13 | _ForumListScreenState createState() => _ForumListScreenState();
14 | }
15 |
16 | class _ForumListScreenState extends State {
17 | String category;
18 |
19 | ForumData forum;
20 | ScrollController scrollController = ScrollController();
21 |
22 | /// Check if the scroll is at the bottom of the page
23 | bool get atBottom =>
24 | scrollController.offset >
25 | (scrollController.position.maxScrollExtent - 200);
26 |
27 | @override
28 | void initState() {
29 | super.initState();
30 | category = Get.arguments['category'];
31 | forum = ForumData(
32 | category: category,
33 | render: (RenderType x) {
34 | if (mounted) setState(() {});
35 | },
36 | );
37 |
38 | ff.fetchPosts(forum);
39 | scrollController.addListener(onScrollToBottom);
40 | }
41 |
42 | ///
43 | onScrollToBottom() {
44 | if (!atBottom) return;
45 | ff.fetchPosts(forum);
46 | }
47 |
48 | @override
49 | Widget build(BuildContext context) {
50 | return Scaffold(
51 | appBar: AppBar(
52 | title: Text(category),
53 | actions: [
54 | IconButton(
55 | icon: Icon(Icons.add),
56 | onPressed: () {
57 | if (ff.notLoggedIn) {
58 | Get.snackbar('로그인', '로그인을 먼저 해 주세요.');
59 | return;
60 | }
61 | if (ff.user.phoneNumber.isNullOrBlank &&
62 | ff.appSetting('block-non-verified-users-to-create') ==
63 | true) {
64 | Get.defaultDialog(
65 | middleText: 'Please verify your phone number first!',
66 | textConfirm: 'Ok',
67 | confirmTextColor: Colors.white,
68 | onConfirm: () => Get.back(),
69 | );
70 | } else {
71 | Get.toNamed('forum-edit', arguments: {'category': category});
72 | }
73 | }),
74 | if (ff.loggedIn)
75 | StreamBuilder(
76 | stream: ff.publicDoc.snapshots(),
77 | builder: (context, AsyncSnapshot snapshot) {
78 | if (snapshot.hasError) return Container();
79 | if (snapshot.connectionState == ConnectionState.waiting)
80 | return Container();
81 | print('data: ${snapshot.data.data()}');
82 | Map data = snapshot.data.data();
83 | bool postEnabled =
84 | data[NotificationOptions.post(category)] ?? false;
85 | bool commentEnabled =
86 | data[NotificationOptions.comment(category)] ?? false;
87 | return Row(children: [
88 | IconButton(
89 | icon: FaIcon(
90 | postEnabled
91 | ? FontAwesomeIcons.solidBell
92 | : FontAwesomeIcons.solidBellSlash,
93 | size: 18,
94 | ),
95 | onPressed: () async {
96 | final String topic = NotificationOptions.post(category);
97 | try {
98 | if (postEnabled) {
99 | await ff.unsubscribeTopic(topic);
100 | } else {
101 | await ff.subscribeTopic(topic);
102 | }
103 | await ff.updateUserPublic(topic, !postEnabled);
104 | } catch (e) {
105 | Get.snackbar('Error', e.toString());
106 | }
107 | },
108 | ),
109 | IconButton(
110 | icon: FaIcon(
111 | commentEnabled
112 | ? FontAwesomeIcons.solidComment
113 | : FontAwesomeIcons.commentSlash,
114 | size: 18,
115 | ),
116 | onPressed: () async {
117 | final String topic =
118 | NotificationOptions.comment(category);
119 | try {
120 | if (commentEnabled) {
121 | await ff.unsubscribeTopic(topic);
122 | } else {
123 | await ff.subscribeTopic(topic);
124 | }
125 | await ff.updateUserPublic(topic, !commentEnabled);
126 | } catch (e) {
127 | Get.snackbar('Error', e.toString());
128 | }
129 | },
130 | ),
131 | ]);
132 | }),
133 | ],
134 | ),
135 | body: Container(
136 | padding: EdgeInsets.all(16),
137 | child: SingleChildScrollView(
138 | controller: scrollController,
139 | child: Column(
140 | children: [
141 | ListView.builder(
142 | physics: NeverScrollableScrollPhysics(),
143 | shrinkWrap: true,
144 | itemCount: forum.posts.length,
145 | itemBuilder: (context, i) {
146 | Map post = forum.posts[i];
147 | return Column(
148 | crossAxisAlignment: CrossAxisAlignment.start,
149 | children: [
150 | PostSubject(post: post),
151 | PostContent(post: post),
152 | DisplayPhotos(files: post['files']),
153 | PostButtons(post: post),
154 | Divider(),
155 | CommentForm(post: post),
156 | if (post['comments'] != null)
157 | for (int j = 0; j < post['comments'].length; j++)
158 | Comment(post: post, index: j),
159 | ],
160 | );
161 | },
162 | ),
163 | if (forum.inLoading) CircularProgressIndicator(),
164 | if (forum.status == ForumStatus.noPosts)
165 | Text('No post exists in this forum.'),
166 | if (forum.status == ForumStatus.noMorePosts)
167 | Text('There is no more post.'),
168 | ],
169 | ),
170 | ),
171 | ),
172 | );
173 | }
174 | }
175 |
176 | class PostButtons extends StatelessWidget {
177 | const PostButtons({
178 | Key key,
179 | @required this.post,
180 | }) : super(key: key);
181 |
182 | final Map post;
183 |
184 | @override
185 | Widget build(BuildContext context) {
186 | return Row(
187 | children: [
188 | PostEditButton(post: post),
189 | RaisedButton(
190 | onPressed: () async {
191 | try {
192 | await ff.deletePost(post['id']);
193 | } catch (e) {
194 | Get.snackbar('Error', e.toString());
195 | }
196 | },
197 | child: Text('Delete'),
198 | ),
199 | if (ff.voteSetting(post['category'], VoteChoice.like))
200 | RaisedButton(
201 | onPressed: () async {
202 | try {
203 | await ff.vote(
204 | postId: post['id'],
205 | choice: VoteChoice.like,
206 | );
207 | } catch (e) {
208 | Get.snackbar('Error', e.toString());
209 | }
210 | },
211 | child: Text('Like ${post['likes'] ?? ''}'),
212 | ),
213 | if (ff.voteSetting(post['category'], VoteChoice.dislike))
214 | TextButton(
215 | onPressed: () async {
216 | try {
217 | await ff.vote(
218 | postId: post['id'],
219 | choice: VoteChoice.dislike,
220 | );
221 | } catch (e) {
222 | Get.snackbar('Error', e.toString());
223 | }
224 | },
225 | child: Text('Dislike ${post['dislikes'] ?? ''}'),
226 | ),
227 | ],
228 | );
229 | }
230 | }
231 |
232 | class PostEditButton extends StatelessWidget {
233 | const PostEditButton({
234 | Key key,
235 | @required this.post,
236 | }) : super(key: key);
237 |
238 | final Map post;
239 |
240 | @override
241 | Widget build(BuildContext context) {
242 | return RaisedButton(
243 | onPressed: () => Get.toNamed(
244 | 'forum-edit',
245 | arguments: {'post': post},
246 | ),
247 | child: Text('Edit'),
248 | );
249 | }
250 | }
251 |
252 | class PostContent extends StatelessWidget {
253 | const PostContent({
254 | Key key,
255 | @required this.post,
256 | }) : super(key: key);
257 |
258 | final Map post;
259 |
260 | @override
261 | Widget build(BuildContext context) {
262 | return Container(
263 | child: Text(post['content']),
264 | color: Colors.grey[200],
265 | margin: EdgeInsets.only(top: 16),
266 | padding: EdgeInsets.all(16),
267 | width: double.infinity,
268 | );
269 | }
270 | }
271 |
272 | class PostSubject extends StatelessWidget {
273 | const PostSubject({
274 | Key key,
275 | @required this.post,
276 | }) : super(key: key);
277 |
278 | final Map post;
279 |
280 | @override
281 | Widget build(BuildContext context) {
282 | return Column(
283 | crossAxisAlignment: CrossAxisAlignment.start,
284 | children: [
285 | Text(
286 | post['title'],
287 | style: TextStyle(fontSize: 22),
288 | ),
289 | Text(
290 | post['id'],
291 | style: TextStyle(fontSize: 10),
292 | ),
293 | ],
294 | );
295 | }
296 | }
297 |
--------------------------------------------------------------------------------
/lib/screens/home/home.screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:fireflutter_sample_app/global_variables.dart';
2 | import 'package:fireflutter_sample_app/keys.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:get/get.dart';
5 |
6 | class HomeScreen extends StatefulWidget {
7 | @override
8 | _HomeScreenState createState() => _HomeScreenState();
9 | }
10 |
11 | class _HomeScreenState extends State {
12 | @override
13 | void initState() {
14 | super.initState();
15 | }
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 | return Scaffold(
20 | key: ValueKey(Keys.homeScreen),
21 | appBar: AppBar(
22 | title: Text('app-name'.tr),
23 | ),
24 | body: Column(
25 | children: [
26 | Text('User Information'),
27 | StreamBuilder(
28 | stream: ff.userChange,
29 | builder: (context, snapshot) {
30 | if (ff.loggedIn) {
31 | return Text(
32 | 'Email: ${ff.user.email}, Color: ${ff.userData['favoriteColor']}, UID: ${ff.user.uid}, displayName: ${ff.user.displayName}, Phone: ${ff.user.phoneNumber},',
33 | key: ValueKey(Keys.hInfo),
34 | );
35 | } else {
36 | return Text(
37 | 'Please login',
38 | key: ValueKey(Keys.hPleaseLogin),
39 | );
40 | }
41 | }),
42 | Divider(),
43 | Text('User Buttons'),
44 | Wrap(
45 | children: [
46 | RaisedButton(
47 | key: ValueKey(Keys.rButton),
48 | onPressed: () => Get.toNamed('register'),
49 | child: Text('Register'),
50 | ),
51 | RaisedButton(
52 | key: ValueKey(Keys.hLoginButton),
53 | onPressed: () => Get.toNamed('login'),
54 | child: Text('Login'),
55 | ),
56 | RaisedButton(
57 | key: ValueKey(Keys.hProfileButotn),
58 | onPressed: () => Get.toNamed('profile'),
59 | child: Text('Profile'),
60 | ),
61 | RaisedButton(
62 | key: ValueKey(Keys.hLogoutButton),
63 | onPressed: ff.logout,
64 | child: Text('Logout'),
65 | ),
66 | RaisedButton(
67 | onPressed: () => Get.toNamed('phone-auth'),
68 | child: Text('Phone Verificatoin'),
69 | ),
70 | RaisedButton(
71 | onPressed: () => Get.toNamed('settings'),
72 | child: Text('Settings'),
73 | ),
74 | DropdownButton(
75 | value: ff.userLanguage,
76 | items: [
77 | DropdownMenuItem(value: 'ko', child: Text('Korean')),
78 | DropdownMenuItem(value: 'en', child: Text('English')),
79 | ],
80 | onChanged: (String value) {
81 | ff.updateProfile({'language': value});
82 | },
83 | ),
84 | ],
85 | ),
86 | if (ff.isAdmin) ...[
87 | Divider(),
88 | RaisedButton(
89 | onPressed: () => Get.toNamed('admin'),
90 | child: Text('Admin Screen'),
91 | ),
92 | ],
93 | Divider(),
94 | Wrap(
95 | children: [
96 | RaisedButton(
97 | onPressed: () =>
98 | Get.toNamed('forum-edit', arguments: {'category': 'qna'}),
99 | child: Text('Create a Post'),
100 | ),
101 | RaisedButton(
102 | onPressed: () =>
103 | Get.toNamed('forum-list', arguments: {'category': 'qna'}),
104 | child: Text('QnA Forum'),
105 | ),
106 | RaisedButton(
107 | onPressed: () => Get.toNamed('forum-list',
108 | arguments: {'category': 'discussion'}),
109 | child: Text('Discussion Forum'),
110 | ),
111 | RaisedButton(
112 | onPressed: () => Get.toNamed('search'),
113 | child: Text('Search'),
114 | ),
115 | ],
116 | ),
117 | Divider(),
118 | RaisedButton(
119 | onPressed: () => Get.toNamed('push-notification'),
120 | child: Text('Push Notification'),
121 | ),
122 | ],
123 | ),
124 | );
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/lib/screens/login/login.screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:fireflutter_sample_app/keys.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:get/get.dart';
4 | import 'package:sign_in_with_apple/sign_in_with_apple.dart';
5 | import '../../global_variables.dart';
6 |
7 | class LoginScreen extends StatefulWidget {
8 | @override
9 | _RegisterScreenState createState() => _RegisterScreenState();
10 | }
11 |
12 | class _RegisterScreenState extends State {
13 | final emailController = TextEditingController();
14 | final passwordController = TextEditingController();
15 | bool loading = false;
16 | @override
17 | Widget build(BuildContext context) {
18 | return Scaffold(
19 | appBar: AppBar(
20 | title: Text('LoginScreen'),
21 | ),
22 | body: Column(
23 | children: [
24 | Text('Social Login'),
25 | Divider(),
26 | RaisedButton(
27 | child: Text('Google Sign-in'),
28 | onPressed: () async {
29 | try {
30 | await ff.signInWithGoogle();
31 | Get.toNamed('home');
32 | } catch (e) {
33 | Get.snackbar('Error', e.toString());
34 | }
35 | },
36 | ),
37 | RaisedButton(
38 | child: Text('Facebook Sign-in'),
39 | onPressed: () async {
40 | try {
41 | await ff.signInWithFacebook();
42 | Get.toNamed('home');
43 | } catch (e) {
44 | Get.snackbar('Error', e.toString());
45 | }
46 | },
47 | ),
48 | if (GetPlatform.isIOS)
49 | SignInWithAppleButton(
50 | onPressed: () async {
51 | try {
52 | await ff.signInWithApple();
53 | Get.toNamed('home');
54 | } catch (e) {
55 | Get.snackbar('Error', e.toString());
56 | }
57 | },
58 | ),
59 | SizedBox(
60 | height: 64,
61 | ),
62 | Text('Eamil & Password Login'),
63 | Divider(),
64 | TextFormField(
65 | key: ValueKey(Keys.lfEmail),
66 | controller: emailController,
67 | decoration: InputDecoration(hintText: 'Email address'),
68 | ),
69 | TextFormField(
70 | key: ValueKey(Keys.lfPassword),
71 | controller: passwordController,
72 | decoration: InputDecoration(hintText: 'Password'),
73 | ),
74 | RaisedButton(
75 | key: ValueKey(Keys.lfSubmitButton),
76 | onPressed: () async {
77 | setState(() => loading = true);
78 | try {
79 | await ff.login(
80 | email: emailController.text,
81 | password: passwordController.text,
82 | );
83 | if (ff.user.phoneNumber.isNullOrBlank &&
84 | ff.appSetting('verify-after-login') == true) {
85 | Get.toNamed('phone-auth');
86 | } else {
87 | Get.toNamed('home');
88 | }
89 | } catch (e) {
90 | Get.snackbar('Error', e.toString());
91 | } finally {
92 | setState(() => loading = false);
93 | }
94 | },
95 | child: loading ? CircularProgressIndicator() : Text('Login'),
96 | ),
97 | ],
98 | ),
99 | );
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/lib/screens/phone_auth/phone_auth.screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:country_code_picker/country_code_picker.dart';
2 | import 'package:fireflutter_sample_app/global_variables.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:get/get.dart';
5 |
6 | class PhoneAuthScreen extends StatefulWidget {
7 | @override
8 | _PhoneAuthScreenState createState() => _PhoneAuthScreenState();
9 | }
10 |
11 | class _PhoneAuthScreenState extends State {
12 | final mobileNumberController = TextEditingController();
13 | String countryCode = "+82";
14 | bool loading = false;
15 |
16 | String get internationalNo => countryCode + mobileNumberController.text;
17 | @override
18 | Widget build(BuildContext context) {
19 | return Scaffold(
20 | appBar: AppBar(
21 | title: Text('Phone Verification'),
22 | ),
23 | body: Padding(
24 | padding: const EdgeInsets.all(16.0),
25 | child: Column(
26 | crossAxisAlignment: CrossAxisAlignment.stretch,
27 | children: [
28 | Text(
29 | 'Choose your country',
30 | style: TextStyle(fontSize: 10),
31 | ),
32 | CountryCodePicker(
33 | onChanged: (country) => countryCode = country.dialCode,
34 | initialSelection: 'KR',
35 | favorite: ['KR', 'PH', 'JP', 'ZH'],
36 | showCountryOnly: false,
37 | showOnlyCountryWhenClosed: true,
38 | alignLeft: true,
39 | ),
40 | Text(
41 | 'Input your mobile number',
42 | style: TextStyle(fontSize: 10),
43 | ),
44 | TextFormField(
45 | controller: mobileNumberController,
46 | keyboardType: TextInputType.number,
47 | style: TextStyle(
48 | fontSize: 32,
49 | ),
50 | decoration: InputDecoration(
51 | hintText: '000-000-000',
52 | hintStyle: TextStyle(
53 | fontSize: 32,
54 | color: Color(0x95959599),
55 | ),
56 | ),
57 | ),
58 | RaisedButton(
59 | onPressed: () async {
60 | if (loading) return;
61 | setState(() => loading = true);
62 |
63 | /// TODO: validate phone number format.
64 | print('no: $internationalNo');
65 | ff.mobileAuthSendCode(internationalNo,
66 | onCodeSent: (verificationID, codeResendToken) {
67 | setState(() => loading = false);
68 | Get.toNamed(
69 | 'phone-auth-code-verification',
70 | arguments: {
71 | 'verificationID': verificationID,
72 | 'codeResendToken': codeResendToken,
73 | 'internationalNo': internationalNo
74 | },
75 | );
76 | }, onError: (e) {
77 | setState(() => loading = false);
78 | Get.snackbar('Error', e.toString());
79 | });
80 | },
81 | child: loading ? CircularProgressIndicator() : Text('SEND CODE'),
82 | ),
83 | if (ff.appSetting('force-verification') != true)
84 | RaisedButton(
85 | onPressed: () => Get.toNamed('home'),
86 | child: Text('SKIP'),
87 | )
88 | ],
89 | ),
90 | ),
91 | );
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/lib/screens/phone_auth/phone_auth_verification_code.screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:fireflutter_sample_app/global_variables.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:get/get.dart';
4 |
5 | class PhoneAuthCodeVerificationScreen extends StatefulWidget {
6 | @override
7 | _PhoneAuthCodeVerificationScreenState createState() =>
8 | _PhoneAuthCodeVerificationScreenState();
9 | }
10 |
11 | class _PhoneAuthCodeVerificationScreenState
12 | extends State {
13 | final codeController = TextEditingController();
14 | bool loading = false;
15 |
16 | String verificationID;
17 | int codeResendToken;
18 | String internationalNo;
19 |
20 | @override
21 | void initState() {
22 | dynamic args = Get.arguments;
23 | verificationID = args['verificationID'];
24 | internationalNo = args['internationalNo'];
25 | codeResendToken = args['codeResendToken'];
26 | super.initState();
27 | }
28 |
29 | @override
30 | Widget build(BuildContext context) {
31 | return Scaffold(
32 | appBar: AppBar(
33 | title: Text('Phone Auth Code Verification'),
34 | ),
35 | body: Column(
36 | children: [
37 | Text('Enter code'),
38 | TextFormField(controller: codeController),
39 | RaisedButton(
40 | child: Text(
41 | "VERIFY",
42 | ),
43 | onPressed: () async {
44 | if (loading) return;
45 | setState(() => loading = true);
46 | try {
47 | await ff.mobileAuthVerifyCode(
48 | code: codeController.text,
49 | verificationId: verificationID,
50 | );
51 | setState(() => loading = false);
52 | Get.toNamed('home');
53 | } catch (e) {
54 | setState(() => loading = false);
55 | Get.snackbar('Error', e.toString());
56 | }
57 | },
58 | ),
59 |
60 | // change number & resend code button.
61 | Row(
62 | children: [
63 | FlatButton(
64 | padding: EdgeInsets.all(0),
65 | child: Text(
66 | 'Resend Code'.tr,
67 | style: TextStyle(
68 | color: Color(0xFF032674),
69 | fontWeight: FontWeight.w400,
70 | ),
71 | ),
72 | onPressed: () {
73 | ff.mobileAuthSendCode(
74 | internationalNo,
75 | resendToken: codeResendToken,
76 | onCodeSent: (_verificationID, resendToken) {
77 | setState(() {
78 | verificationID = _verificationID;
79 | codeResendToken = resendToken;
80 | });
81 | },
82 | onError: (e) => Get.snackbar('Error', e.toString()),
83 | );
84 | },
85 | ),
86 | Spacer(),
87 | FlatButton(
88 | padding: EdgeInsets.all(0),
89 | child: Text(
90 | 'Change Number'.tr,
91 | style: TextStyle(
92 | color: Color(0xFF032674),
93 | fontWeight: FontWeight.w400,
94 | ),
95 | ),
96 | onPressed: () {
97 | Get.back();
98 | },
99 | ),
100 | ],
101 | ),
102 | ],
103 | ),
104 | );
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/lib/screens/profile/profile.screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:fireflutter/fireflutter.dart';
2 | import 'package:fireflutter_sample_app/global_variables.dart';
3 | import 'package:fireflutter_sample_app/keys.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | import 'package:get/get.dart';
7 | import 'package:image_picker/image_picker.dart';
8 |
9 | class ProfileScreen extends StatefulWidget {
10 | @override
11 | _RegisterScreenState createState() => _RegisterScreenState();
12 | }
13 |
14 | class _RegisterScreenState extends State {
15 | TextEditingController displayNameController =
16 | TextEditingController(text: ff.user?.displayName ?? '');
17 | TextEditingController favoriteColorController =
18 | TextEditingController(text: ff.userData['favoriteColor']);
19 |
20 | bool loading = false;
21 | double uploadProgress = 0;
22 | @override
23 | Widget build(BuildContext context) {
24 | return Scaffold(
25 | appBar: AppBar(
26 | title: Text('ProfileScreen'),
27 | ),
28 | body: ff.notLoggedIn
29 | ? Text('Please login')
30 | : Column(
31 | children: [
32 | StreamBuilder(
33 | stream: ff.userChange,
34 | builder: (context, snapshot) {
35 | if (ff.notLoggedIn || ff.user.photoURL == null)
36 | return Container();
37 | return SizedBox(
38 | width: 120,
39 | height: 120,
40 | child: Image.network(ff.user.photoURL));
41 | }),
42 | RaisedButton(
43 | onPressed: () async {
44 | ImageSource source = await showDialog(
45 | context: context,
46 | builder: (_) => AlertDialog(
47 | title: Text('Choose Camera or Gallery'),
48 | content: Column(
49 | mainAxisSize: MainAxisSize.min,
50 | children: [
51 | TextButton(
52 | onPressed: () =>
53 | Get.back(result: ImageSource.camera),
54 | child: Text('Camera'),
55 | ),
56 | TextButton(
57 | onPressed: () =>
58 | Get.back(result: ImageSource.gallery),
59 | child: Text('Gallery'),
60 | ),
61 | ],
62 | ),
63 | ),
64 | );
65 |
66 | if (source == null) return null;
67 |
68 | try {
69 | if (!ff.user.photoURL.isNullOrBlank) {
70 | await ff.deleteFile(ff.user.photoURL);
71 | }
72 | final url = await ff.uploadFile(
73 | folder: 'user-profile-photos',
74 | source: source,
75 | progress: (p) =>
76 | setState(() => this.uploadProgress = p),
77 | );
78 | await ff.updatePhoto(url);
79 | setState(() => uploadProgress = 0);
80 | } catch (e) {
81 | Get.snackbar('Error', e.toString());
82 | }
83 | },
84 | child: Text('Upload Profile Photo'),
85 | ),
86 | if (ff.user.photoURL.isNullOrBlank)
87 | RaisedButton(
88 | onPressed: () async {
89 | if (!ff.user.photoURL.isNullOrBlank) {
90 | await ff.deleteFile(ff.user.photoURL);
91 | await ff.updatePhoto('');
92 | }
93 | },
94 | child: Text('Delete Profile Photo')),
95 | if (uploadProgress != 0) Text('$uploadProgress%'),
96 | Text('My Email: ${ff.user.email}'),
97 | TextFormField(
98 | key: ValueKey(Keys.pfDisplayName),
99 | controller: displayNameController,
100 | decoration: InputDecoration(hintText: 'displayName'),
101 | ),
102 | TextFormField(
103 | key: ValueKey(Keys.pfColor),
104 | controller: favoriteColorController,
105 | decoration:
106 | InputDecoration(hintText: 'What is your favorite color?'),
107 | ),
108 | RaisedButton(
109 | key: ValueKey(Keys.pfSubmitButton),
110 | onPressed: () async {
111 | setState(() => loading = true);
112 | try {
113 | await ff.updateProfile({
114 | 'displayName': displayNameController.text,
115 | 'favoriteColor': favoriteColorController.text
116 | }, public: {
117 | notifyPost: true,
118 | notifyComment: true,
119 | });
120 | setState(() => loading = false);
121 |
122 | Get.snackbar('Success', 'Profile has been updated!');
123 | } catch (e) {
124 | setState(() => loading = false);
125 | Get.snackbar('Error', e.toString());
126 | }
127 | },
128 | child: loading ? CircularProgressIndicator() : Text('Update'),
129 | ),
130 | ],
131 | ),
132 | );
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/lib/screens/push-notification/push-notification.screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:fireflutter_sample_app/global_variables.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:get/get.dart';
4 |
5 | class PushNotification extends StatefulWidget {
6 | @override
7 | _PushNotificationState createState() => _PushNotificationState();
8 | }
9 |
10 | class _PushNotificationState extends State {
11 | @override
12 | Widget build(BuildContext context) {
13 | return Scaffold(
14 | appBar: AppBar(
15 | title: Text('Push Notification'.tr),
16 | ),
17 | body: Column(
18 | children: [
19 | StreamBuilder(
20 | stream: ff.userChange,
21 | builder: (context, snapshot) {
22 | if (ff.userIsLoggedIn) {
23 | return Text(
24 | 'Email: ${ff.user.email}, displayName: ${ff.user.displayName}');
25 | } else {
26 | return Text('You are not logged in.');
27 | }
28 | }),
29 | Divider(),
30 | Text('Device Token: '),
31 | Text(ff.firebaseMessagingToken),
32 | RaisedButton(
33 | onPressed: () async {
34 | ff.sendNotification(
35 | 'Sample push notification to topic',
36 | 'This is the content of push to topic',
37 | screen: 'home',
38 | topic: ff.allTopic,
39 | test: true,
40 | );
41 | },
42 | child: Text('Send notification to all uers(allTopic)'),
43 | ),
44 | RaisedButton(
45 | onPressed: () async {
46 | ff.sendNotification(
47 | 'Sample push notification to me',
48 | 'This is the content of push to token',
49 | screen: 'home',
50 | token: ff.firebaseMessagingToken,
51 | test: true,
52 | );
53 | },
54 | child: Text('Send notification to me(my token)'),
55 | ),
56 | RaisedButton(
57 | onPressed: () async {
58 | ff.sendNotification(
59 | 'Sample push notification to my devices',
60 | 'This is the content of push to tokens',
61 | screen: 'home',
62 | tokens: [ff.firebaseMessagingToken],
63 | test: true,
64 | );
65 | },
66 | child: Text('Send notification to my devices(multi tokens)'),
67 | ),
68 | ],
69 | ),
70 | );
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/lib/screens/register/register.screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:fireflutter/fireflutter.dart';
2 | import 'package:fireflutter_sample_app/global_variables.dart';
3 | import 'package:fireflutter_sample_app/keys.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:get/get.dart';
6 |
7 | class RegisterScreen extends StatefulWidget {
8 | @override
9 | _RegisterScreenState createState() => _RegisterScreenState();
10 | }
11 |
12 | class _RegisterScreenState extends State {
13 | TextEditingController emailController = TextEditingController();
14 | TextEditingController passwordController = TextEditingController();
15 | TextEditingController displayNameController = TextEditingController();
16 | TextEditingController favoriteColorController = TextEditingController();
17 |
18 | bool loading = false;
19 | @override
20 | Widget build(BuildContext context) {
21 | return Scaffold(
22 | key: ValueKey('registerScreen'),
23 | appBar: AppBar(
24 | title: Text('Register'),
25 | ),
26 | body: Column(
27 | children: [
28 | TextFormField(
29 | key: ValueKey(Keys.riEmail),
30 | controller: emailController,
31 | decoration: InputDecoration(hintText: 'Email Address'),
32 | ),
33 | TextFormField(
34 | key: ValueKey(Keys.riPassword),
35 | controller: passwordController,
36 | decoration: InputDecoration(hintText: 'Password'),
37 | ),
38 | TextFormField(
39 | key: ValueKey(Keys.riDisplayName),
40 | controller: displayNameController,
41 | decoration: InputDecoration(hintText: 'displayName'),
42 | ),
43 | TextFormField(
44 | key: ValueKey(Keys.riColor),
45 | controller: favoriteColorController,
46 | decoration:
47 | InputDecoration(hintText: 'What is your favorite color?'),
48 | ),
49 | RaisedButton(
50 | key: ValueKey(Keys.rsButton),
51 | onPressed: () async {
52 | setState(() => loading = true);
53 | try {
54 | await ff.register({
55 | 'email': emailController.text,
56 | 'password': passwordController.text,
57 | 'displayName': displayNameController.text,
58 | 'favoriteColor': favoriteColorController.text
59 | }, public: {
60 | notifyPost: true,
61 | notifyComment: true,
62 | });
63 |
64 | setState(() => loading = false);
65 | if (ff.appSetting('verify-after-register') == true) {
66 | Get.toNamed('phone-auth');
67 | } else {
68 | Get.toNamed('home');
69 | }
70 | } catch (e) {
71 | setState(() => loading = false);
72 | Get.snackbar('Error', e.toString());
73 | }
74 | },
75 | child: loading ? CircularProgressIndicator() : Text('Register'),
76 | ),
77 | ],
78 | ),
79 | );
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/lib/screens/search/search.screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:fireflutter_sample_app/global_variables.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:get/get.dart';
4 |
5 | class SearchScreen extends StatefulWidget {
6 | @override
7 | _SearchScreenState createState() => _SearchScreenState();
8 | }
9 |
10 | class _SearchScreenState extends State {
11 | TextEditingController searchController = TextEditingController();
12 | List