diff --git a/examples/flutter-user-management/README.md b/examples/flutter-user-management/README.md
new file mode 100644
index 00000000000..164f52c99cc
--- /dev/null
+++ b/examples/flutter-user-management/README.md
@@ -0,0 +1,110 @@
+# Supabase Flutter User Management
+
+This example will set you up for a very common situation: users can sign up with a magic link and then update their account with public profile information, including a profile image.
+
+## Technologies used
+
+- Frontend:
+ - [Flutter SDK](https://flutter.dev/) - Google's UI toolkit for crafting beautiful, natively compiled applications for mobile, web, and desktop from a single codebase.
+ - [supabase_flutter](https://pub.dev/packages/supabase_flutter) for user management and image storage uploading.
+- Backend:
+ - [app.supabase.io](https://app.supabase.io/): hosted Postgres database with restful API for usage with supabase_flutter.
+
+## Build from scratch
+
+### 1. Create new project
+
+Sign up to Supabase - [https://app.supabase.io](https://app.supabase.io) and create a new project. Wait for your database to start.
+
+### 2. Run "User Management" Quickstart
+
+Once your database has started, run the "User Management Starter" quickstart. Inside of your project, enter the `SQL editor` tab and scroll down until you see `User Management Starter: Set up a Public Profiles table which you can access with your API`.
+
+### 3. Get the URL and Key
+
+Go to the Project Settings (the cog icon), open the API tab, and find your API URL and `anon` key, you'll need these in the next step.
+
+The `anon` key is your client-side API key. It allows "anonymous access" to your database, until the user has logged in. Once they have logged in, the keys will switch to the user's own login token. This enables row level security for your data. Read more about this [below](#postgres-row-level-security).
+
+
+
+**_NOTE_**: The `service_role` key has full access to your data, bypassing any security policies. These keys have to be kept secret and are meant to be used in server environments and never on a client or browser.
+
+### 4. Setup deeplink redirect urls
+
+Go to the Authentication Settings page (the user icon). Enter the flutter app redirect url below into `Additional Redirect URLs` field. Then click Save.
+
+> io.supabase.flutterdemo://login-callback
+
+
+
+### 5. Run the flutter application
+
+- Go to `lib/utils/constants.dart` file
+- Update `SUPABASE_URL` and `SUPABASE_ANNON_KEY` with your URL and Key
+- Run the application: `flutter run`
+
+## Supabase details
+
+### Postgres Row level security
+
+This project uses very high-level Authorization using Postgres' Role Level Security.
+When you start a Postgres database on Supabase, we populate it with an `auth` schema, and some helper functions.
+When a user logs in, they are issued a JWT with the role `authenticated` and thier UUID.
+We can use these details to provide fine-grained control over what each user can and cannot do.
+
+This is a trimmed-down schema, with the policies:
+
+```sql
+-- Create a table for Public Profiles
+create table profiles (
+ id uuid references auth.users not null,
+ updated_at timestamp with time zone,
+ username text unique,
+ avatar_url text,
+ website text,
+
+ primary key (id),
+ unique(username),
+ constraint username_length check (char_length(username) >= 3)
+);
+
+alter table profiles enable row level security;
+
+create policy "Public profiles are viewable by everyone."
+ on profiles for select
+ using ( true );
+
+create policy "Users can insert their own profile."
+ on profiles for insert
+ with check ( auth.uid() = id );
+
+create policy "Users can update own profile."
+ on profiles for update
+ using ( auth.uid() = id );
+
+-- Set up Realtime!
+begin;
+ drop publication if exists supabase_realtime;
+ create publication supabase_realtime;
+commit;
+alter publication supabase_realtime add table profiles;
+
+-- Set up Storage!
+insert into storage.buckets (id, name)
+values ('avatars', 'avatars');
+
+create policy "Avatar images are publicly accessible."
+ on storage.objects for select
+ using ( bucket_id = 'avatars' );
+
+create policy "Anyone can upload an avatar."
+ on storage.objects for insert
+ with check ( bucket_id = 'avatars' );
+```
+
+## Authors
+
+- [Supabase](https://supabase.io)
+
+Supabase is open source. We'd love for you to follow along and get involved at https://github.com/supabase/supabase
diff --git a/examples/flutter-user-management/analysis_options.yaml b/examples/flutter-user-management/analysis_options.yaml
new file mode 100644
index 00000000000..dc21fdb52bd
--- /dev/null
+++ b/examples/flutter-user-management/analysis_options.yaml
@@ -0,0 +1,5 @@
+include: package:lint/analysis_options.yaml
+
+linter:
+ rules:
+ avoid_print: false
\ No newline at end of file
diff --git a/examples/flutter-user-management/android/.gitignore b/examples/flutter-user-management/android/.gitignore
new file mode 100644
index 00000000000..0a741cb43d6
--- /dev/null
+++ b/examples/flutter-user-management/android/.gitignore
@@ -0,0 +1,11 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
+
+# Remember to never publicly share your keystore.
+# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
+key.properties
diff --git a/examples/flutter-user-management/android/app/build.gradle b/examples/flutter-user-management/android/app/build.gradle
new file mode 100644
index 00000000000..fec8b364067
--- /dev/null
+++ b/examples/flutter-user-management/android/app/build.gradle
@@ -0,0 +1,66 @@
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withReader('UTF-8') { reader ->
+ localProperties.load(reader)
+ }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+ throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
+if (flutterVersionCode == null) {
+ flutterVersionCode = '1'
+}
+
+def flutterVersionName = localProperties.getProperty('flutter.versionName')
+if (flutterVersionName == null) {
+ flutterVersionName = '1.0'
+}
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+ compileSdkVersion 29
+
+ sourceSets {
+ main.java.srcDirs += 'src/main/kotlin'
+ }
+
+ lintOptions {
+ disable 'InvalidPackage'
+ }
+
+ defaultConfig {
+ // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
+ applicationId "io.supabase.demoapp"
+ minSdkVersion 20
+ targetSdkVersion 29
+ versionCode flutterVersionCode.toInteger()
+ versionName flutterVersionName
+ manifestPlaceholders = [
+ 'appAuthRedirectScheme': 'io.supabase.demoapp'
+ ]
+ }
+
+ buildTypes {
+ release {
+ // TODO: Add your own signing config for the release build.
+ // Signing with the debug keys for now, so `flutter run --release` works.
+ signingConfig signingConfigs.debug
+ }
+ }
+}
+
+flutter {
+ source '../..'
+}
+
+dependencies {
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
diff --git a/examples/flutter-user-management/android/app/src/debug/AndroidManifest.xml b/examples/flutter-user-management/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 00000000000..5f5a7501249
--- /dev/null
+++ b/examples/flutter-user-management/android/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/examples/flutter-user-management/android/app/src/main/AndroidManifest.xml b/examples/flutter-user-management/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000000..e21232c0b30
--- /dev/null
+++ b/examples/flutter-user-management/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/flutter-user-management/android/app/src/main/kotlin/io/supabase/demoapp/MainActivity.kt b/examples/flutter-user-management/android/app/src/main/kotlin/io/supabase/demoapp/MainActivity.kt
new file mode 100644
index 00000000000..93dc3a7f29d
--- /dev/null
+++ b/examples/flutter-user-management/android/app/src/main/kotlin/io/supabase/demoapp/MainActivity.kt
@@ -0,0 +1,6 @@
+package io.supabase.demoapp
+
+import io.flutter.embedding.android.FlutterActivity
+
+class MainActivity: FlutterActivity() {
+}
diff --git a/examples/flutter-user-management/android/app/src/main/res/drawable/launch_background.xml b/examples/flutter-user-management/android/app/src/main/res/drawable/launch_background.xml
new file mode 100644
index 00000000000..304732f8842
--- /dev/null
+++ b/examples/flutter-user-management/android/app/src/main/res/drawable/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/examples/flutter-user-management/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/examples/flutter-user-management/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 00000000000..db77bb4b7b0
Binary files /dev/null and b/examples/flutter-user-management/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/examples/flutter-user-management/android/app/src/main/res/mipmap-hdpi/launcher_icon.png b/examples/flutter-user-management/android/app/src/main/res/mipmap-hdpi/launcher_icon.png
new file mode 100644
index 00000000000..723eb74a137
Binary files /dev/null and b/examples/flutter-user-management/android/app/src/main/res/mipmap-hdpi/launcher_icon.png differ
diff --git a/examples/flutter-user-management/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/examples/flutter-user-management/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 00000000000..17987b79bb8
Binary files /dev/null and b/examples/flutter-user-management/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/examples/flutter-user-management/android/app/src/main/res/mipmap-mdpi/launcher_icon.png b/examples/flutter-user-management/android/app/src/main/res/mipmap-mdpi/launcher_icon.png
new file mode 100644
index 00000000000..430bf39102a
Binary files /dev/null and b/examples/flutter-user-management/android/app/src/main/res/mipmap-mdpi/launcher_icon.png differ
diff --git a/examples/flutter-user-management/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/examples/flutter-user-management/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 00000000000..09d4391482b
Binary files /dev/null and b/examples/flutter-user-management/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/examples/flutter-user-management/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png b/examples/flutter-user-management/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png
new file mode 100644
index 00000000000..4ebd28f0eb5
Binary files /dev/null and b/examples/flutter-user-management/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png differ
diff --git a/examples/flutter-user-management/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/examples/flutter-user-management/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 00000000000..d5f1c8d34e7
Binary files /dev/null and b/examples/flutter-user-management/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/examples/flutter-user-management/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png b/examples/flutter-user-management/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png
new file mode 100644
index 00000000000..184a0496390
Binary files /dev/null and b/examples/flutter-user-management/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png differ
diff --git a/examples/flutter-user-management/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/examples/flutter-user-management/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 00000000000..4d6372eebdb
Binary files /dev/null and b/examples/flutter-user-management/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/examples/flutter-user-management/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png b/examples/flutter-user-management/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png
new file mode 100644
index 00000000000..fff447baf83
Binary files /dev/null and b/examples/flutter-user-management/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png differ
diff --git a/examples/flutter-user-management/android/app/src/main/res/values/styles.xml b/examples/flutter-user-management/android/app/src/main/res/values/styles.xml
new file mode 100644
index 00000000000..1f83a33fd4f
--- /dev/null
+++ b/examples/flutter-user-management/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/examples/flutter-user-management/android/app/src/profile/AndroidManifest.xml b/examples/flutter-user-management/android/app/src/profile/AndroidManifest.xml
new file mode 100644
index 00000000000..5f5a7501249
--- /dev/null
+++ b/examples/flutter-user-management/android/app/src/profile/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/examples/flutter-user-management/android/build.gradle b/examples/flutter-user-management/android/build.gradle
new file mode 100644
index 00000000000..3100ad2d555
--- /dev/null
+++ b/examples/flutter-user-management/android/build.gradle
@@ -0,0 +1,31 @@
+buildscript {
+ ext.kotlin_version = '1.3.50'
+ repositories {
+ google()
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.5.0'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+ project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+ project.evaluationDependsOn(':app')
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/examples/flutter-user-management/android/gradle.properties b/examples/flutter-user-management/android/gradle.properties
new file mode 100644
index 00000000000..a6738207fd1
--- /dev/null
+++ b/examples/flutter-user-management/android/gradle.properties
@@ -0,0 +1,4 @@
+org.gradle.jvmargs=-Xmx1536M
+android.useAndroidX=true
+android.enableJetifier=true
+android.enableR8=true
diff --git a/examples/flutter-user-management/android/gradle/wrapper/gradle-wrapper.properties b/examples/flutter-user-management/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000000..296b146b731
--- /dev/null
+++ b/examples/flutter-user-management/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Jun 23 08:50:38 CEST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
diff --git a/examples/flutter-user-management/android/settings.gradle b/examples/flutter-user-management/android/settings.gradle
new file mode 100644
index 00000000000..44e62bcf06a
--- /dev/null
+++ b/examples/flutter-user-management/android/settings.gradle
@@ -0,0 +1,11 @@
+include ':app'
+
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
+
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
+
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/examples/flutter-user-management/assets/images/logo-dark.png b/examples/flutter-user-management/assets/images/logo-dark.png
new file mode 100644
index 00000000000..f78a307b925
Binary files /dev/null and b/examples/flutter-user-management/assets/images/logo-dark.png differ
diff --git a/examples/flutter-user-management/assets/images/logo.png b/examples/flutter-user-management/assets/images/logo.png
new file mode 100644
index 00000000000..0ae50c18140
Binary files /dev/null and b/examples/flutter-user-management/assets/images/logo.png differ
diff --git a/examples/flutter-user-management/assets/images/noavatar.jpeg b/examples/flutter-user-management/assets/images/noavatar.jpeg
new file mode 100644
index 00000000000..d096544006d
Binary files /dev/null and b/examples/flutter-user-management/assets/images/noavatar.jpeg differ
diff --git a/examples/flutter-user-management/ios/.gitignore b/examples/flutter-user-management/ios/.gitignore
new file mode 100644
index 00000000000..e96ef602b8d
--- /dev/null
+++ b/examples/flutter-user-management/ios/.gitignore
@@ -0,0 +1,32 @@
+*.mode1v3
+*.mode2v3
+*.moved-aside
+*.pbxuser
+*.perspectivev3
+**/*sync/
+.sconsign.dblite
+.tags*
+**/.vagrant/
+**/DerivedData/
+Icon?
+**/Pods/
+**/.symlinks/
+profile
+xcuserdata
+**/.generated/
+Flutter/App.framework
+Flutter/Flutter.framework
+Flutter/Flutter.podspec
+Flutter/Generated.xcconfig
+Flutter/app.flx
+Flutter/app.zip
+Flutter/flutter_assets/
+Flutter/flutter_export_environment.sh
+ServiceDefinitions.json
+Runner/GeneratedPluginRegistrant.*
+
+# Exceptions to above rules.
+!default.mode1v3
+!default.mode2v3
+!default.pbxuser
+!default.perspectivev3
diff --git a/examples/flutter-user-management/ios/Flutter/AppFrameworkInfo.plist b/examples/flutter-user-management/ios/Flutter/AppFrameworkInfo.plist
new file mode 100644
index 00000000000..6b4c0f78a78
--- /dev/null
+++ b/examples/flutter-user-management/ios/Flutter/AppFrameworkInfo.plist
@@ -0,0 +1,26 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ App
+ CFBundleIdentifier
+ io.flutter.flutter.app
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ App
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ MinimumOSVersion
+ 8.0
+
+
diff --git a/examples/flutter-user-management/ios/Flutter/Debug.xcconfig b/examples/flutter-user-management/ios/Flutter/Debug.xcconfig
new file mode 100644
index 00000000000..ec97fc6f302
--- /dev/null
+++ b/examples/flutter-user-management/ios/Flutter/Debug.xcconfig
@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
+#include "Generated.xcconfig"
diff --git a/examples/flutter-user-management/ios/Flutter/Release.xcconfig b/examples/flutter-user-management/ios/Flutter/Release.xcconfig
new file mode 100644
index 00000000000..c4855bfe200
--- /dev/null
+++ b/examples/flutter-user-management/ios/Flutter/Release.xcconfig
@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
+#include "Generated.xcconfig"
diff --git a/examples/flutter-user-management/ios/Podfile b/examples/flutter-user-management/ios/Podfile
new file mode 100644
index 00000000000..1e8c3c90a55
--- /dev/null
+++ b/examples/flutter-user-management/ios/Podfile
@@ -0,0 +1,41 @@
+# Uncomment this line to define a global platform for your project
+# platform :ios, '9.0'
+
+# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
+ENV['COCOAPODS_DISABLE_STATS'] = 'true'
+
+project 'Runner', {
+ 'Debug' => :debug,
+ 'Profile' => :release,
+ 'Release' => :release,
+}
+
+def flutter_root
+ generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
+ unless File.exist?(generated_xcode_build_settings_path)
+ raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
+ end
+
+ File.foreach(generated_xcode_build_settings_path) do |line|
+ matches = line.match(/FLUTTER_ROOT\=(.*)/)
+ return matches[1].strip if matches
+ end
+ raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
+end
+
+require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
+
+flutter_ios_podfile_setup
+
+target 'Runner' do
+ use_frameworks!
+ use_modular_headers!
+
+ flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
+end
+
+post_install do |installer|
+ installer.pods_project.targets.each do |target|
+ flutter_additional_ios_build_settings(target)
+ end
+end
diff --git a/examples/flutter-user-management/ios/Runner.xcodeproj/project.pbxproj b/examples/flutter-user-management/ios/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 00000000000..f5a49818750
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,495 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
+ 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
+ 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 97C146EB1CF9000F007C117D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 9740EEB11CF90186004384FC /* Flutter */ = {
+ isa = PBXGroup;
+ children = (
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */,
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */,
+ );
+ name = Flutter;
+ sourceTree = "";
+ };
+ 97C146E51CF9000F007C117D = {
+ isa = PBXGroup;
+ children = (
+ 9740EEB11CF90186004384FC /* Flutter */,
+ 97C146F01CF9000F007C117D /* Runner */,
+ 97C146EF1CF9000F007C117D /* Products */,
+ );
+ sourceTree = "";
+ };
+ 97C146EF1CF9000F007C117D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146EE1CF9000F007C117D /* Runner.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 97C146F01CF9000F007C117D /* Runner */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146FA1CF9000F007C117D /* Main.storyboard */,
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */,
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
+ 97C147021CF9000F007C117D /* Info.plist */,
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
+ );
+ path = Runner;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 97C146ED1CF9000F007C117D /* Runner */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
+ buildPhases = (
+ 9740EEB61CF901F6004384FC /* Run Script */,
+ 97C146EA1CF9000F007C117D /* Sources */,
+ 97C146EB1CF9000F007C117D /* Frameworks */,
+ 97C146EC1CF9000F007C117D /* Resources */,
+ 9705A1C41CF9048500538489 /* Embed Frameworks */,
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Runner;
+ productName = Runner;
+ productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 97C146E61CF9000F007C117D /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 1020;
+ ORGANIZATIONNAME = "";
+ TargetAttributes = {
+ 97C146ED1CF9000F007C117D = {
+ CreatedOnToolsVersion = 7.3.1;
+ LastSwiftMigration = 1100;
+ };
+ };
+ };
+ buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 97C146E51CF9000F007C117D;
+ productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 97C146ED1CF9000F007C117D /* Runner */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 97C146EC1CF9000F007C117D /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Thin Binary";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
+ };
+ 9740EEB61CF901F6004384FC /* Run Script */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run Script";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 97C146EA1CF9000F007C117D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C146FB1CF9000F007C117D /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C147001CF9000F007C117D /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 249021D3217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Profile;
+ };
+ 249021D4217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = io.supabase.demoapp;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Profile;
+ };
+ 97C147031CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 97C147041CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 97C147061CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = io.supabase.demoapp;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Debug;
+ };
+ 97C147071CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = io.supabase.demoapp;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147031CF9000F007C117D /* Debug */,
+ 97C147041CF9000F007C117D /* Release */,
+ 249021D3217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147061CF9000F007C117D /* Debug */,
+ 97C147071CF9000F007C117D /* Release */,
+ 249021D4217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 97C146E61CF9000F007C117D /* Project object */;
+}
\ No newline at end of file
diff --git a/examples/flutter-user-management/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/flutter-user-management/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000000..1d526a16ed0
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/examples/flutter-user-management/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/flutter-user-management/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 00000000000..18d981003d6
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/examples/flutter-user-management/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/examples/flutter-user-management/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 00000000000..f9b0d7c5ea1
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+
+
+
+
+ PreviewsEnabled
+
+
+
diff --git a/examples/flutter-user-management/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/examples/flutter-user-management/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
new file mode 100644
index 00000000000..a28140cfdb3
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/flutter-user-management/ios/Runner.xcworkspace/contents.xcworkspacedata b/examples/flutter-user-management/ios/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000000..1d526a16ed0
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/examples/flutter-user-management/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/flutter-user-management/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 00000000000..18d981003d6
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/examples/flutter-user-management/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/examples/flutter-user-management/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 00000000000..f9b0d7c5ea1
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+
+
+
+
+ PreviewsEnabled
+
+
+
diff --git a/examples/flutter-user-management/ios/Runner/AppDelegate.swift b/examples/flutter-user-management/ios/Runner/AppDelegate.swift
new file mode 100644
index 00000000000..70693e4a8c1
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner/AppDelegate.swift
@@ -0,0 +1,13 @@
+import UIKit
+import Flutter
+
+@UIApplicationMain
+@objc class AppDelegate: FlutterAppDelegate {
+ override func application(
+ _ application: UIApplication,
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
+ ) -> Bool {
+ GeneratedPluginRegistrant.register(with: self)
+ return super.application(application, didFinishLaunchingWithOptions: launchOptions)
+ }
+}
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 00000000000..d36b1fab2d9
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,122 @@
+{
+ "images" : [
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "83.5x83.5",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-83.5x83.5@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "1024x1024",
+ "idiom" : "ios-marketing",
+ "filename" : "Icon-App-1024x1024@1x.png",
+ "scale" : "1x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
new file mode 100644
index 00000000000..1f362942b97
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
new file mode 100644
index 00000000000..138f10b2dbe
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
new file mode 100644
index 00000000000..69d63cea798
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
new file mode 100644
index 00000000000..44bc2d6f0bb
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
new file mode 100644
index 00000000000..bef965285cb
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
new file mode 100644
index 00000000000..9246fcbd058
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
new file mode 100644
index 00000000000..cf3ad32d52e
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
new file mode 100644
index 00000000000..69d63cea798
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
new file mode 100644
index 00000000000..e47d503fa5d
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
new file mode 100644
index 00000000000..73502aff8c9
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
new file mode 100644
index 00000000000..73502aff8c9
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
new file mode 100644
index 00000000000..abb4d37291f
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
new file mode 100644
index 00000000000..8d81ca60ef0
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
new file mode 100644
index 00000000000..855e1198810
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
new file mode 100644
index 00000000000..34989d35504
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/examples/flutter-user-management/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
new file mode 100644
index 00000000000..0bedcf2fd46
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
new file mode 100644
index 00000000000..9da19eacad3
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
new file mode 100644
index 00000000000..9da19eacad3
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/examples/flutter-user-management/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
new file mode 100644
index 00000000000..9da19eacad3
Binary files /dev/null and b/examples/flutter-user-management/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ
diff --git a/examples/flutter-user-management/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/examples/flutter-user-management/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
new file mode 100644
index 00000000000..89c2725b70f
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
@@ -0,0 +1,5 @@
+# Launch Screen Assets
+
+You can customize the launch screen with your own desired assets by replacing the image files in this directory.
+
+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.
\ No newline at end of file
diff --git a/examples/flutter-user-management/ios/Runner/Base.lproj/LaunchScreen.storyboard b/examples/flutter-user-management/ios/Runner/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 00000000000..f2e259c7c93
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/flutter-user-management/ios/Runner/Base.lproj/Main.storyboard b/examples/flutter-user-management/ios/Runner/Base.lproj/Main.storyboard
new file mode 100644
index 00000000000..f3c28516fb3
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner/Base.lproj/Main.storyboard
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/flutter-user-management/ios/Runner/Info.plist b/examples/flutter-user-management/ios/Runner/Info.plist
new file mode 100644
index 00000000000..fb546c6d4ba
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner/Info.plist
@@ -0,0 +1,57 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ Supabase Demo
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(FLUTTER_BUILD_NAME)
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ $(FLUTTER_BUILD_NUMBER)
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UIViewControllerBasedStatusBarAppearance
+
+ CFBundleURLTypes
+
+
+ CFBundleTypeRole
+ Editor
+ CFBundleURLSchemes
+
+
+ io.supabase.flutterdemo
+
+
+
+
+
diff --git a/examples/flutter-user-management/ios/Runner/Runner-Bridging-Header.h b/examples/flutter-user-management/ios/Runner/Runner-Bridging-Header.h
new file mode 100644
index 00000000000..308a2a560b4
--- /dev/null
+++ b/examples/flutter-user-management/ios/Runner/Runner-Bridging-Header.h
@@ -0,0 +1 @@
+#import "GeneratedPluginRegistrant.h"
diff --git a/examples/flutter-user-management/lib/components/auth_required_state.dart b/examples/flutter-user-management/lib/components/auth_required_state.dart
new file mode 100644
index 00000000000..5e72a96042d
--- /dev/null
+++ b/examples/flutter-user-management/lib/components/auth_required_state.dart
@@ -0,0 +1,10 @@
+import 'package:flutter/material.dart';
+import 'package:supabase_flutter/supabase_flutter.dart';
+
+class AuthRequiredState
+ extends SupabaseAuthRequiredState {
+ @override
+ void onUnauthenticated() {
+ Navigator.pushNamedAndRemoveUntil(context, '/signIn', (route) => false);
+ }
+}
diff --git a/examples/flutter-user-management/lib/components/auth_state.dart b/examples/flutter-user-management/lib/components/auth_state.dart
new file mode 100644
index 00000000000..6ba3c67425b
--- /dev/null
+++ b/examples/flutter-user-management/lib/components/auth_state.dart
@@ -0,0 +1,26 @@
+import 'package:flutter/material.dart';
+import 'package:supabase/supabase.dart' as supabase;
+import 'package:supabase_flutter/supabase_flutter.dart';
+
+class AuthState extends SupabaseAuthState {
+ @override
+ void onUnauthenticated() {
+ Navigator.pushNamedAndRemoveUntil(context, '/signIn', (route) => false);
+ }
+
+ @override
+ void onAuthenticated(supabase.Session session) {
+ Navigator.pushNamedAndRemoveUntil(context, '/profile', (route) => false);
+ }
+
+ @override
+ void onPasswordRecovery(supabase.Session session) {
+ Navigator.pushNamedAndRemoveUntil(
+ context, '/profile/changePassword', (route) => false);
+ }
+
+ @override
+ void onErrorAuthenticating(String message) {
+ print('***** onErrorAuthenticating: $message');
+ }
+}
diff --git a/examples/flutter-user-management/lib/main.dart b/examples/flutter-user-management/lib/main.dart
new file mode 100644
index 00000000000..2e18a081cbb
--- /dev/null
+++ b/examples/flutter-user-management/lib/main.dart
@@ -0,0 +1,37 @@
+import 'package:supabase_demo/screens/profile_screen.dart';
+import 'package:flutter/material.dart';
+import 'package:supabase_demo/screens/signin_screen.dart';
+import 'package:supabase_demo/screens/splash_screen.dart';
+import 'package:supabase_demo/utils/constants.dart';
+import 'package:supabase_flutter/supabase_flutter.dart';
+
+void main() {
+ WidgetsFlutterBinding.ensureInitialized();
+
+ // init Supabase singleton
+ Supabase(
+ url: supabaseUrl,
+ anonKey: supabaseAnnonKey,
+ authCallbackUrlHostname: 'login-callback',
+ debug: true,
+ );
+
+ runApp(MyApp());
+}
+
+class MyApp extends StatelessWidget {
+ // This widget is the root of your application.
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ title: 'Supabase Demo',
+ theme: ThemeData.dark(),
+ initialRoute: '/',
+ routes: {
+ '/': (_) => SplashScreen(),
+ '/signIn': (_) => SignInScreen(),
+ '/profile': (_) => ProfileScreen(),
+ },
+ );
+ }
+}
diff --git a/examples/flutter-user-management/lib/screens/profile_screen.dart b/examples/flutter-user-management/lib/screens/profile_screen.dart
new file mode 100644
index 00000000000..6d67fab114c
--- /dev/null
+++ b/examples/flutter-user-management/lib/screens/profile_screen.dart
@@ -0,0 +1,294 @@
+import 'dart:io';
+import 'dart:typed_data';
+
+import 'package:supabase_demo/components/auth_required_state.dart';
+import 'package:supabase_demo/utils/helpers.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:gotrue/gotrue.dart';
+import 'package:path/path.dart';
+import 'package:rounded_loading_button/rounded_loading_button.dart';
+import 'package:image_picker/image_picker.dart';
+import 'package:supabase_flutter/supabase_flutter.dart';
+
+class ProfileScreen extends StatefulWidget {
+ @override
+ _ProfileScreenState createState() => _ProfileScreenState();
+}
+
+class _ProfileScreenState extends AuthRequiredState {
+ _ProfileScreenState();
+
+ final scaffoldKey = GlobalKey();
+
+ final RoundedLoadingButtonController _signOutBtnController =
+ RoundedLoadingButtonController();
+ final RoundedLoadingButtonController _updateProfileBtnController =
+ RoundedLoadingButtonController();
+
+ final _picker = ImagePicker();
+
+ User? user;
+ bool loadingProfile = true;
+ String _appBarTitle = '';
+ String username = '';
+ String website = '';
+ String avatarUrl = '';
+
+ @override
+ void initState() {
+ super.initState();
+
+ final _user = Supabase().client.auth.user();
+ if (_user != null) {
+ setState(() {
+ _appBarTitle = 'Welcome ${_user.email}';
+ user = _user;
+ });
+ loadProfile(_user.id);
+ }
+ }
+
+ Future loadProfile(String userId) async {
+ final response = await Supabase()
+ .client
+ .from('profiles')
+ .select('username, website, avatar_url')
+ .eq('id', userId)
+ .single()
+ .execute();
+ if (response.error == null && response.data != null) {
+ setState(() {
+ username = response.data['username'] as String? ?? '';
+ website = response.data['website'] as String? ?? '';
+ avatarUrl = response.data['avatar_url'] as String? ?? '';
+ loadingProfile = false;
+ });
+ } else {
+ setState(() {
+ loadingProfile = false;
+ });
+ }
+ return true;
+ }
+
+ final picker = ImagePicker();
+
+ Future updateAvatar(BuildContext context) async {
+ final pickedFile = await _picker.getImage(source: ImageSource.camera);
+ if (pickedFile != null) {
+ final file = File(pickedFile.path);
+ final fileExt = extension(file.path);
+ final fileName = '${randomString(15)}$fileExt';
+
+ final response = await Supabase()
+ .client
+ .storage
+ .from('avatars')
+ .upload(fileName, file);
+ if (response.error == null) {
+ setState(() {
+ avatarUrl = fileName;
+ });
+ _onUpdateProfilePress(context);
+ } else {
+ print(response.error!.message);
+ }
+ }
+ }
+
+ Future _onSignOutPress(BuildContext context) async {
+ await Supabase().client.auth.signOut();
+ Navigator.pushNamedAndRemoveUntil(context, '/signIn', (route) => false);
+ return true;
+ }
+
+ Future _onUpdateProfilePress(BuildContext context) async {
+ FocusScope.of(context).unfocus();
+
+ final updates = {
+ 'id': user?.id,
+ 'username': username,
+ 'website': website,
+ 'avatar_url': avatarUrl,
+ 'updated_at': DateTime.now().toString(),
+ };
+
+ final response =
+ await Supabase().client.from('profiles').upsert(updates).execute();
+ if (response.error != null) {
+ showMessage("Update profile failed: ${response.error!.message}");
+ _updateProfileBtnController.reset();
+ return false;
+ } else {
+ _updateProfileBtnController.reset();
+ showMessage("Profile updated!");
+ return true;
+ }
+ }
+
+ void showMessage(String message) {
+ final snackbar = SnackBar(content: Text(message));
+ ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(snackbar);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ key: scaffoldKey,
+ resizeToAvoidBottomInset: false,
+ appBar: AppBar(
+ title: Text(_appBarTitle),
+ ),
+ body: loadingProfile
+ ? SizedBox(
+ height: MediaQuery.of(context).size.height / 1.3,
+ child: const Center(
+ child: CircularProgressIndicator(),
+ ),
+ )
+ : Padding(
+ padding: const EdgeInsets.all(15.0),
+ child: Column(
+ children: [
+ AvatarContainer(
+ url: avatarUrl,
+ onUpdatePressed: () => updateAvatar(context),
+ key: Key(avatarUrl),
+ ),
+ TextFormField(
+ onChanged: (value) => setState(() {
+ username = value;
+ }),
+ initialValue: username,
+ keyboardType: TextInputType.emailAddress,
+ decoration: const InputDecoration(
+ labelText: 'Username',
+ hintText: '',
+ ),
+ ),
+ TextFormField(
+ onChanged: (value) => setState(() {
+ website = value;
+ }),
+ initialValue: website,
+ keyboardType: TextInputType.emailAddress,
+ decoration: const InputDecoration(
+ labelText: 'Website',
+ hintText: '',
+ ),
+ ),
+ const SizedBox(height: 35.0),
+ RoundedLoadingButton(
+ color: Colors.green,
+ controller: _updateProfileBtnController,
+ onPressed: () {
+ _onUpdateProfilePress(context);
+ },
+ child: const Text('Update profile',
+ style: TextStyle(fontSize: 20, color: Colors.white)),
+ ),
+ const SizedBox(height: 35.0),
+ RoundedLoadingButton(
+ color: Colors.red,
+ controller: _signOutBtnController,
+ onPressed: () {
+ _onSignOutPress(context);
+ },
+ child: const Text(
+ 'Sign out',
+ style: TextStyle(fontSize: 20, color: Colors.white),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+class AvatarContainer extends StatefulWidget {
+ final String url;
+ final void Function() onUpdatePressed;
+ const AvatarContainer(
+ {required this.url, required this.onUpdatePressed, Key? key})
+ : super(key: key);
+
+ @override
+ _AvatarContainerState createState() => _AvatarContainerState();
+}
+
+class _AvatarContainerState extends State {
+ _AvatarContainerState();
+
+ bool loadingImage = true;
+ Uint8List? image;
+
+ @override
+ void initState() {
+ super.initState();
+
+ if (widget.url != '') {
+ downloadImage(widget.url);
+ }
+ }
+
+ Future downloadImage(String path) async {
+ setState(() {
+ loadingImage = true;
+ });
+
+ final response =
+ await Supabase().client.storage.from('avatars').download(path);
+ if (response.error == null) {
+ setState(() {
+ image = response.data;
+ loadingImage = false;
+ });
+ } else {
+ print(response.error!.message);
+ setState(() {
+ loadingImage = false;
+ });
+ }
+ return true;
+ }
+
+ ImageProvider