### Define Installation Rules Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/example/windows/CMakeLists.txt Configures the installation of the executable, Flutter assets, and required libraries. ```cmake # === Installation === # Support files are copied into place next to the executable, so that it can # run in place. This is done instead of making a separate bundle (as on Linux) # so that building and running from within Visual Studio will work. set(BUILD_BUNDLE_DIR "$") # Make the "install" step default, as it's required to run. set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) if(PLUGIN_BUNDLED_LIBRARIES) install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) # Install the AOT library on non-Debug builds only. install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" CONFIGURATIONS Profile;Release COMPONENT Runtime) ``` -------------------------------- ### Supabase SQL for Profile Management and Realtime Setup Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/example/README.md This SQL script sets up the necessary database schema for user profiles in Supabase, including table creation, row-level security policies, and enabling realtime subscriptions. It also configures storage for avatars and associated access 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'); create policy "Anyone can update an avatar." on storage.objects for update with check (bucket_id = 'avatars'); ``` -------------------------------- ### Install and Bootstrap Melos Source: https://github.com/supabase/supabase-flutter/blob/main/AGENTS.md Install the Melos tool globally and then bootstrap dependencies for all packages in the monorepo. ```bash dart pub global activate melos melos bootstrap # or shorthand: melos bs ``` -------------------------------- ### Run Tests with Docker Services Source: https://github.com/supabase/supabase-flutter/blob/main/AGENTS.md Instructions for starting Docker services, running tests sequentially for packages requiring them, and stopping services. ```bash # 1. Start Docker services cd infra/ docker compose up -d # 2. Run tests (from package directory) cd ../../packages/ dart test -j 1 # 3. Stop Docker services when done cd ../../infra/ docker compose down ``` -------------------------------- ### Supabase Authentication Examples Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/README.md Perform common authentication actions such as sign up, login with email and password, and magic link. Also, demonstrates how to listen to authentication state changes. ```dart final supabase = Supabase.instance.client; // Email and password sign up await supabase.auth.signUp( email: email, password: password, ); // Email and password login await supabase.auth.signInWithPassword( email: email, password: password, ); // Magic link login await supabase.auth.signInWithOtp(email: 'my_email@example.com'); // Listen to auth state changes supabase.auth.onAuthStateChange.listen((data) { final AuthChangeEvent event = data.event; final Session? session = data.session; // Do something when there is an auth event }); ``` -------------------------------- ### PostgREST Query Building Example Source: https://github.com/supabase/supabase-flutter/blob/main/AGENTS.md Demonstrates the builder pattern for constructing PostgREST queries, chaining methods for selection and filtering. ```dart supabase.from('users').select('id, name').eq('id', 1).limit(10) ``` -------------------------------- ### Setup Flutter Tool Backend Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/example/windows/flutter/CMakeLists.txt Configures the custom command and target to invoke the Flutter tool for build assembly. ```cmake # === Flutter tool backend === # _phony_ is a non-existent file to force this command to run every time, # since currently there's no way to get a full input/output list from the # flutter tool. set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) add_custom_command( OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ${CPP_WRAPPER_SOURCES_APP} ${PHONY_OUTPUT} COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" windows-x64 $ VERBATIM ) add_custom_target(flutter_assemble DEPENDS "${FLUTTER_LIBRARY}" ${FLUTTER_LIBRARY_HEADERS} ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ${CPP_WRAPPER_SOURCES_APP} ) ``` -------------------------------- ### Admin API: Create, List, and Delete Users Source: https://context7.com/supabase/supabase-flutter/llms.txt Provides examples for server-side operations using the Admin API, including creating users with specific attributes, listing users with pagination, and deleting users. Requires the service-role key. ```dart final UserResponse newUser = await supabase.auth.admin.createUser( AdminUserAttributes( email: 'admin-created@example.com', password: 'temporaryPass123', emailConfirm: true, userMetadata: {'role': 'moderator'}, ), ); print('Created: ${newUser.user?.id}'); final List users = await supabase.auth.admin.listUsers( page: 1, perPage: 50, ); print('Total fetched: ${users.length}'); await supabase.auth.admin.deleteUser(newUser.user!.id); ``` -------------------------------- ### Import Supabase Flutter Package Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/README.md Import the supabase_flutter package to start using its functionalities. ```dart import 'package:supabase_flutter/supabase_flutter.dart'; ``` -------------------------------- ### Configure Application Installation and Bundling Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/example/linux/CMakeLists.txt Defines the installation logic for the Flutter application, including cleaning the bundle directory and copying the executable, ICU data, and plugin libraries. It ensures a clean state by removing stale assets before each install. ```cmake set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") install(CODE " file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") " COMPONENT Runtime) install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) ``` -------------------------------- ### Supabase.initialize Source: https://context7.com/supabase/supabase-flutter/llms.txt Bootstrap the Flutter SDK by calling this once in main(). It creates and stores a singleton SupabaseClient. Access the client later via Supabase.instance.client. ```APIDOC ## Supabase.initialize — Bootstrap the Flutter SDK Call this once in `main()` before `runApp()`. It creates and stores a singleton `SupabaseClient`. Access the client later via `Supabase.instance.client`. ```dart import 'package:supabase_flutter/supabase_flutter.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Supabase.initialize( url: 'https://xyzcompany.supabase.co', publishableKey: 'your-anon-key', // Optional: custom auth options authOptions: const FlutterAuthClientOptions( authFlowType: AuthFlowType.pkce, ), // Optional: custom realtime options realtimeClientOptions: const RealtimeClientOptions( logLevel: RealtimeLogLevel.info, ), // Optional: enable verbose debug logging debug: true, ); runApp(const MyApp()); } // Convenient global accessor used throughout the app final supabase = Supabase.instance.client; ``` ``` -------------------------------- ### Install AOT Library (CMake) Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/example/linux/CMakeLists.txt Installs the AOT library on non-debug builds using CMake. This ensures that the library is only deployed when needed, optimizing build sizes for release versions. ```cmake if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() ``` -------------------------------- ### Get public URL for bucket objects Source: https://context7.com/supabase/supabase-flutter/llms.txt Retrieve the public URL for objects in a bucket. Image transformations can be applied. ```dart final String publicUrl = supabase.storage .from('avatars') .getPublicUrl('public/alice/avatar.png'); ``` ```dart final String transformedUrl = supabase.storage .from('avatars') .getPublicUrl( 'public/alice/avatar.png', transform: const TransformOptions(width: 200, height: 200), ); ``` -------------------------------- ### Initialize Supabase Flutter SDK Source: https://context7.com/supabase/supabase-flutter/llms.txt Call this once in main() before runApp(). It creates and stores a singleton SupabaseClient. Access the client later via Supabase.instance.client. Optional parameters allow for custom auth and realtime client options, as well as verbose debug logging. ```dart import 'package:supabase_flutter/supabase_flutter.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Supabase.initialize( url: 'https://xyzcompany.supabase.co', publishableKey: 'your-anon-key', // Optional: custom auth options authOptions: const FlutterAuthClientOptions( authFlowType: AuthFlowType.pkce, ), // Optional: custom realtime options realtimeClientOptions: const RealtimeClientOptions( logLevel: RealtimeLogLevel.info, ), // Optional: enable verbose debug logging debug: true, ); runApp(const MyApp()); } // Convenient global accessor used throughout the app final supabase = Supabase.instance.client; ``` -------------------------------- ### signUp Source: https://context7.com/supabase/supabase-flutter/llms.txt Create a new user account using email and password, or phone number and password. ```APIDOC ### `signUp` — Create a new user account ```dart // Email + password sign-up final AuthResponse res = await supabase.auth.signUp( email: 'user@example.com', password: 's3cr3tP@ssw0rd', data: {'username': 'alice', 'avatar_url': 'https://example.com/alice.png'}, emailRedirectTo: 'io.supabase.myapp://login-callback', ); final Session? session = res.session; final User? user = res.user; print('User id: ${user?.id}'); // Phone + password sign-up await supabase.auth.signUp( phone: '+15551234567', password: 's3cr3tP@ssw0rd', channel: OtpChannel.sms, // or OtpChannel.whatsapp ); ``` ``` -------------------------------- ### Get public URL for objects Source: https://context7.com/supabase/supabase-flutter/llms.txt Retrieves the public URL for an object in a bucket that is configured for public access. Supports applying transformations. ```APIDOC ## `getPublicUrl` — Get public URL for public bucket objects ### Description Retrieves the public URL for an object in a bucket that is configured for public access. Supports applying transformations. ### Method `getPublicUrl` ### Endpoint `supabase.storage.from('').getPublicUrl('')` ### Parameters #### Path Parameters - **bucket_name** (string) - Required - The name of the storage bucket. - **path** (string) - Required - The path to the object within the bucket. #### Query Parameters - **transform** (`TransformOptions`) - Optional - Options for transforming the image during URL generation: - **width** (int) - Optional - Desired width. - **height** (int) - Optional - Desired height. ### Request Example ```dart final String publicUrl = supabase.storage .from('avatars') .getPublicUrl('public/alice/avatar.png'); // With image transform final String transformedUrl = supabase.storage .from('avatars') .getPublicUrl( 'public/alice/avatar.png', transform: const TransformOptions(width: 200, height: 200), ); ``` ### Response #### Success Response (200) - **publicUrl** (string) - The public URL of the object. ``` -------------------------------- ### Initialize Supabase Client for Local Testing Source: https://github.com/supabase/supabase-flutter/blob/main/AGENTS.md Use this code to initialize the Supabase client when testing against a local Supabase instance. Ensure you replace 'your-local-supabase-key' with your actual local key. ```dart await Supabase.initialize( url: 'http://localhost:54321', publishableKey: 'your-local-supabase-key', ); ``` -------------------------------- ### Run a Single Test File Source: https://github.com/supabase/supabase-flutter/blob/main/AGENTS.md Execute a specific test file or a test case matching a pattern from within the package directory. ```bash # From package directory dart test test/specific_test.dart # For a specific test case dart test test/specific_test.dart -n "test name pattern" ``` -------------------------------- ### Invoke Supabase Edge Functions Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/README.md Call Supabase Edge Functions directly using the `invoke` method. This example shows how to call a function named 'get_countries'. ```dart final data = await supabase.functions.invoke('get_countries'); ``` -------------------------------- ### Manage Storage Buckets with `createBucket`, `getBucket`, `listBuckets` Source: https://context7.com/supabase/supabase-flutter/llms.txt Perform operations on Supabase Storage buckets, including creating new buckets with specific options (public access, file size limits, allowed MIME types), listing existing buckets, and updating their settings. ```dart // Create a public bucket final String bucketId = await supabase.storage.createBucket( 'avatars', const BucketOptions( public: true, fileSizeLimit: '5MB', allowedMimeTypes: ['image/jpeg', 'image/png', 'image/webp'], ), ); print('Created bucket: $bucketId'); // List all buckets final List buckets = await supabase.storage.listBuckets(); for (final b in buckets) { print('${b.id}: public=${b.public}'); } // Update bucket settings await supabase.storage.updateBucket( 'avatars', const BucketOptions(public: false), ); // Delete a bucket (must be empty) await supabase.storage.deleteBucket('avatars'); ``` -------------------------------- ### Database CRUD Operations with Supabase Flutter Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/README.md Perform basic CRUD operations on your Supabase database using the SDK. This example demonstrates selecting data with filters and inserting a new row. ```dart // Select data with filters final data = await supabase .from('cities') .select() .eq('country_id', 1) // equals filter .neq('name', 'The shire'); // does not equal filter // Insert a new row await supabase .from('cities') .insert({'name': 'The Shire', 'country_id': 554}); ``` -------------------------------- ### Configure Flutter Windows Build Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/example/windows/flutter/CMakeLists.txt Sets up the Flutter library, includes, and dependencies for a Windows build environment. ```cmake cmake_minimum_required(VERSION 3.14) set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") # Configuration provided via flutter tool. include(${EPHEMERAL_DIR}/generated_config.cmake) # TODO: Move the rest of this into files in ephemeral. See # https://github.com/flutter/flutter/issues/57146. set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") # === Flutter Library === set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") # Published to parent scope for install step. set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) list(APPEND FLUTTER_LIBRARY_HEADERS "flutter_export.h" "flutter_windows.h" "flutter_messenger.h" "flutter_plugin_registrar.h" "flutter_texture_registrar.h" ) list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") add_library(flutter INTERFACE) target_include_directories(flutter INTERFACE "${EPHEMERAL_DIR}" ) target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") add_dependencies(flutter flutter_assemble) ``` -------------------------------- ### Initialize Supabase with MigrationLocalStorage Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/README.md Initialize Supabase using `MigrationLocalStorage` to enable automatic migration of user sessions from Hive to SharedPreferences. Ensure the `persistSessionKey` is correctly configured. ```dart Supabase.initialize( // ... authOptions: FlutterAuthClientOptions( localStorage: const MigrationLocalStorage( persistSessionKey: "sb-${Uri.parse(url).host.split(".").first}-auth-token", ), ), ); ``` -------------------------------- ### Native Google Sign-In with Supabase Flutter Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/README.md Perform native Google Sign-In on Android and iOS. Ensure you have configured client IDs in your Supabase dashboard and followed the google_sign_in package setup. The web client ID is required for all platforms, and the iOS client ID is specifically for iOS. ```dart import 'package:google_sign_in/google_sign_in.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; ... Future _googleSignIn() async { /// TODO: update the Web client ID with your own. /// /// Web Client ID that you registered with Google Cloud. const webClientId = 'my-web.apps.googleusercontent.com'; /// TODO: update the iOS client ID with your own. /// /// iOS Client ID that you registered with Google Cloud. const iosClientId = 'my-ios.apps.googleusercontent.com'; // Google sign in on Android will work without providing the Android // Client ID registered on Google Cloud. final GoogleSignIn signIn = GoogleSignIn.instance; // At the start of your app, initialize the GoogleSignIn instance unawaited( signIn.initialize(clientId: iosClientId, serverClientId: webClientId)); // Perform the sign in final googleAccount = await signIn.authenticate(); final googleAuthorization = await googleAccount.authorizationClient.authorizationForScopes([]); final googleAuthentication = googleAccount!.authentication; final idToken = googleAuthentication.idToken; final accessToken = googleAuthorization.accessToken; if (idToken == null) { throw 'No ID Token found.'; } return supabase.auth.signInWithIdToken( provider: OAuthProvider.google, idToken: idToken, accessToken: accessToken, ); } ... ``` -------------------------------- ### Sign Up with Email and Password Source: https://context7.com/supabase/supabase-flutter/llms.txt Creates a new user account with email and password. Optionally, you can provide user metadata and a redirect URL for email verification. Supports phone number sign-up with SMS or WhatsApp OTP. ```dart // Email + password sign-up final AuthResponse res = await supabase.auth.signUp( email: 'user@example.com', password: 's3cr3tP@ssw0rd', data: {'username': 'alice', 'avatar_url': 'https://example.com/alice.png'}, emailRedirectTo: 'io.supabase.myapp://login-callback', ); final Session? session = res.session; final User? user = res.user; print('User id: ${user?.id}'); // Phone + password sign-up await supabase.auth.signUp( phone: '+15551234567', password: 's3cr3tP@ssw0rd', channel: OtpChannel.sms, // or OtpChannel.whatsapp ); ``` -------------------------------- ### Configure CMake Project and Build Modes Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/example/windows/CMakeLists.txt Sets up the project name, minimum CMake version, and defines build configuration types for Debug, Profile, and Release modes. ```cmake cmake_minimum_required(VERSION 3.14) project(example LANGUAGES CXX) # The name of the executable created for the application. Change this to change # the on-disk name of your application. set(BINARY_NAME "example") # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. cmake_policy(SET CMP0063 NEW) # Define build configuration option. get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(IS_MULTICONFIG) set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" CACHE STRING "" FORCE) else() if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Flutter build mode" FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Profile" "Release") endif() endif() # Define settings for the Profile build mode. set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") # Use Unicode for all projects. add_definitions(-DUNICODE -D_UNICODE) ``` -------------------------------- ### signInWithOtp Source: https://context7.com/supabase/supabase-flutter/llms.txt Initiate a magic link or OTP login flow via email or SMS. ```APIDOC ### `signInWithOtp` — Magic link / OTP login ```dart // Send magic link to email await supabase.auth.signInWithOtp( email: 'user@example.com', emailRedirectTo: 'io.supabase.myapp://login-callback', shouldCreateUser: false, // don't create user if they don't exist ); // Send SMS OTP to phone await supabase.auth.signInWithOtp( phone: '+15551234567', channel: OtpChannel.sms, ); // Verify the OTP received via SMS final AuthResponse verifyRes = await supabase.auth.verifyOTP( phone: '+15551234567', token: '123456', type: OtpType.sms, ); print('Verified: ${verifyRes.user?.id}'); ``` ``` -------------------------------- ### createBucket / getBucket / listBuckets — Manage buckets Source: https://context7.com/supabase/supabase-flutter/llms.txt Provides functionalities to manage storage buckets, including creating new buckets with specific configurations, retrieving bucket details, listing all available buckets, and deleting buckets. ```APIDOC ## Storage — `supabase.storage` ### createBucket / getBucket / listBuckets — Manage buckets ### Description Manage buckets. ### Usage ```dart // Create a public bucket final String bucketId = await supabase.storage.createBucket( 'avatars', const BucketOptions( public: true, fileSizeLimit: '5MB', allowedMimeTypes: ['image/jpeg', 'image/png', 'image/webp'], ), ); print('Created bucket: $bucketId'); // List all buckets final List buckets = await supabase.storage.listBuckets(); for (final b in buckets) { print('${b.id}: public=${b.public}'); } // Update bucket settings await supabase.storage.updateBucket( 'avatars', const BucketOptions(public: false), ); // Delete a bucket (must be empty) await supabase.storage.deleteBucket('avatars'); ``` ``` -------------------------------- ### Run Tests with Coverage Source: https://github.com/supabase/supabase-flutter/blob/main/AGENTS.md Generate test coverage reports for all packages. Can be run from the root or package directory. ```bash # From root or package directory melos run test:coverage ``` -------------------------------- ### Database: Select Rows Source: https://context7.com/supabase/supabase-flutter/llms.txt Demonstrates how to query rows from a table using `supabase.from().select()`. Supports selecting all columns, specific columns with joins, and retrieving the total count of rows. ```dart final List> all = await supabase.from('countries').select(); final data = await supabase .from('cities') .select('id, name, countries(name)'); final PostgrestResponse>> response = await supabase.from('cities').select().count(CountOption.exact); print('Total rows: ${response.count}'); ``` -------------------------------- ### Sign In with Email or Phone Source: https://context7.com/supabase/supabase-flutter/llms.txt Logs in an existing user using their email address or phone number and password. Returns an access token upon successful authentication. ```dart final AuthResponse res = await supabase.auth.signInWithPassword( email: 'user@example.com', password: 's3cr3tP@ssw0rd', ); // Or via phone number final AuthResponse phoneRes = await supabase.auth.signInWithPassword( phone: '+15551234567', password: 's3cr3tP@ssw0rd', ); final String accessToken = res.session!.accessToken; print('Logged in as ${res.user!.email}'); ``` -------------------------------- ### Manage infrastructure and run tests Source: https://github.com/supabase/supabase-flutter/blob/main/README.md Commands to manage the Docker-based services required for testing and executing Dart tests. The tests are run sequentially to avoid conflicts with shared services. ```bash docker compose up -d dart test -j 1 docker compose down ``` -------------------------------- ### Run Linting and Formatting Checks Source: https://github.com/supabase/supabase-flutter/blob/main/AGENTS.md Execute all static analysis checks, including linting and code formatting, across all packages. ```bash melos run lint:all # Run analyzer on all packages melos run analyze # Format code (80 char line length) melos run format ``` -------------------------------- ### Online Presence Tracking with `onPresence` and `track` Source: https://context7.com/supabase/supabase-flutter/llms.txt Manage user online presence using Supabase Realtime. Track user status, receive join/leave events, and sync presence state. Requires authentication. ```dart final channel = supabase.channel('online-users'); channel .onPresence( event: PresenceEvent.sync, callback: (_) { final state = channel.presenceState(); print('Online users: ${state.keys.length}'); }, ) .onPresence( event: PresenceEvent.join, callback: (payload) => print('Joined: ${payload.newPresences}'), ) .onPresence( event: PresenceEvent.leave, callback: (payload) => print('Left: ${payload.leftPresences}'), ) .subscribe((status, [_]) async { if (status == RealtimeSubscribeStatus.subscribed) { // Broadcast current user's presence state await channel.track({ 'user_id': supabase.auth.currentUser!.id, 'online_at': DateTime.now().toIso8601String(), 'username': 'alice', }); } }); // Untrack (mark as offline) without unsubscribing await channel.untrack(); ``` -------------------------------- ### Database: Insert Rows Source: https://context7.com/supabase/supabase-flutter/llms.txt Shows how to insert data into tables using `supabase.from().insert()`. Supports inserting a single row, inserting and returning the created row, and bulk inserts. ```dart await supabase.from('messages').insert({ 'message': 'Hello world', 'username': 'alice', 'channel_id': 1, }); final List> created = await supabase .from('messages') .insert({'message': 'Hi!', 'username': 'bob', 'channel_id': 2}) .select(); print('Created: ${created.first}'); await supabase.from('messages').insert([ {'message': 'Msg 1', 'username': 'alice', 'channel_id': 1}, {'message': 'Msg 2', 'username': 'bob', 'channel_id': 1}, ]); ``` -------------------------------- ### Include Flutter and Plugin Build Rules Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/example/windows/CMakeLists.txt Includes the necessary subdirectories and generated plugin files for the Flutter build process. ```cmake # Flutter library and tool build rules. set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") add_subdirectory(${FLUTTER_MANAGED_DIR}) # Application build; see runner/CMakeLists.txt. add_subdirectory("runner") # Generated plugin build rules, which manage building the plugins and adding # them to the application. include(flutter/generated_plugins.cmake) ``` -------------------------------- ### Finding and Checking System Libraries with PkgConfig Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/example/linux/flutter/CMakeLists.txt Uses PkgConfig to find and check for required system libraries: GTK, GLIB, and GIO. This ensures that the necessary development files for these libraries are available before proceeding with the build. It defines imported targets for each library. ```cmake # === Flutter Library === # System-level dependencies. find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) ``` -------------------------------- ### Enroll, Challenge, and Verify MFA Factors Source: https://context7.com/supabase/supabase-flutter/llms.txt Demonstrates the flow for enrolling a TOTP factor, creating an MFA challenge, and verifying it with a user-provided code. Requires the user to have an authenticator app set up. ```dart final AuthMFAEnrollResponse enrollRes = await supabase.auth.mfa.enroll( factorType: FactorType.totp, friendlyName: 'My Authenticator App', issuer: 'myapp.com', ); // Show enrollRes.totp!.qrCode (SVG) or enrollRes.totp!.secret to user final AuthMFAChallengeResponse challengeRes = await supabase.auth.mfa.challenge(factorId: enrollRes.id); final AuthMFAVerifyResponse verifyRes = await supabase.auth.mfa.verify( factorId: enrollRes.id, challengeId: challengeRes.id, code: '123456', ); print('AAL level: ${verifyRes.level}'); // aal2 // Unenroll a factor await supabase.auth.mfa.unenroll(enrollRes.id); ``` -------------------------------- ### Sign in with GitHub OAuth Source: https://context7.com/supabase/supabase-flutter/llms.txt Initiates the OAuth flow for GitHub. Ensure your deep link is configured correctly to handle the redirect. The `onAuthStateChange` stream should be used to listen for the sign-in completion. ```dart await supabase.auth.signInWithOAuth( OAuthProvider.github, redirectTo: kIsWeb ? null : 'io.supabase.myapp://login-callback', scopes: 'repo gist', ); // Listen for the sign-in completion supabase.auth.onAuthStateChange.listen( (data) { if (data.event == AuthChangeEvent.signedIn) { print('OAuth sign-in complete: ${data.session?.user.email}'); // Navigate to home screen } }, onError: (error) => print('Auth error: $error'), ); ``` -------------------------------- ### Initialize Supabase Client Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/README.md Initialize the Supabase client with your project's URL and public key before running your Flutter application. It's recommended to ensure Flutter bindings are initialized first. ```dart import 'package:supabase_flutter/supabase_flutter.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Supabase.initialize( url: SUPABASE_URL, publishableKey: SUPABASE_KEY, ); runApp(MyApp()); } // It's handy to then extract the Supabase client in a variable for later uses final supabase = Supabase.instance.client; ``` -------------------------------- ### Create signed upload URLs for delegated uploads Source: https://context7.com/supabase/supabase-flutter/llms.txt Generate a signed upload URL for client-side direct uploads. The token is valid for a specified duration. ```dart final SignedUploadURLResponse signedUpload = await supabase.storage .from('user-uploads') .createSignedUploadUrl('images/user-photo.jpg'); ``` ```dart await supabase.storage .from('user-uploads') .uploadToSignedUrl( signedUpload.path, signedUpload.token, File('/local/photo.jpg'), ); ``` -------------------------------- ### Real-time Database Stream with `StreamBuilder` Source: https://context7.com/supabase/supabase-flutter/llms.txt Set up a real-time stream for a Supabase table using `supabase.from().stream()`. This is ideal for displaying live data updates in Flutter widgets using `StreamBuilder`. ```dart class CountriesWidget extends StatefulWidget { const CountriesWidget({super.key}); @override State createState() => _CountriesWidgetState(); } class _CountriesWidgetState extends State { // Persist the stream to prevent reconnects on rebuild final _stream = supabase .from('countries') .stream(primaryKey: ['id']) .order('name') .limit(100); @override Widget build(BuildContext context) { return StreamBuilder>>( stream: _stream, builder: (context, snapshot) { if (!snapshot.hasData) return const CircularProgressIndicator(); final countries = snapshot.data!; return ListView.builder( itemCount: countries.length, itemBuilder: (_, i) => ListTile(title: Text(countries[i]['name'])), ); }, ); } } ``` -------------------------------- ### Migrate Local Storage from Hive to SharedPreferences Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/README.md Implement `MigrationLocalStorage` to automatically migrate user sessions from Hive to SharedPreferences. This class handles the initialization and migration logic, ensuring a smooth transition for existing users. ```dart const _hiveBoxName = 'supabase_authentication'; class MigrationLocalStorage extends LocalStorage { final SharedPreferencesLocalStorage sharedPreferencesLocalStorage; late final HiveLocalStorage hiveLocalStorage; MigrationLocalStorage({required String persistSessionKey}) : sharedPreferencesLocalStorage = SharedPreferencesLocalStorage(persistSessionKey: persistSessionKey); @override Future initialize() async { await Hive.initFlutter('auth'); hiveLocalStorage = const HiveLocalStorage(); await sharedPreferencesLocalStorage.initialize(); try { await migrate(); } on TimeoutException { // Ignore TimeoutException thrown by Hive methods // https://github.com/supabase/supabase-flutter/issues/794 } } @visibleForTesting Future migrate() async { // Migrate from Hive to SharedPreferences if (await Hive.boxExists(_hiveBoxName)) { await hiveLocalStorage.initialize(); final hasHive = await hiveLocalStorage.hasAccessToken(); if (hasHive) { final accessToken = await hiveLocalStorage.accessToken(); final session = Session.fromJson(jsonDecode(accessToken!)['currentSession']); if (session == null) { return; } await sharedPreferencesLocalStorage .persistSession(jsonEncode(session.toJson())); await hiveLocalStorage.removePersistedSession(); } if (Hive.box(_hiveBoxName).isEmpty) { final boxPath = Hive.box(_hiveBoxName).path; await Hive.deleteBoxFromDisk(_hiveBoxName); //Delete `auth` folder if it's empty if (!kIsWeb && boxPath != null) { final boxDir = File(boxPath).parent; final dirIsEmpty = await boxDir.list().length == 0; if (dirIsEmpty) { await boxDir.delete(); } } } } } @override Future accessToken() { return sharedPreferencesLocalStorage.accessToken(); } @override Future hasAccessToken() { return sharedPreferencesLocalStorage.hasAccessToken(); } @override Future persistSession(String persistSessionString) { return sharedPreferencesLocalStorage.persistSession(persistSessionString); } @override Future removePersistedSession() { return sharedPreferencesLocalStorage.removePersistedSession(); } } /// A [LocalStorage] implementation that implements Hive as the /// storage method. class HiveLocalStorage extends LocalStorage { /// Creates a LocalStorage instance that implements the Hive Database const HiveLocalStorage(); /// The encryption key used by Hive. If null, the box is not encrypted /// /// This value should not be redefined in runtime, otherwise the user may /// not be fetched correctly /// /// See also: /// /// * static String? encryptionKey; @override Future initialize() async { HiveCipher? encryptionCipher; if (encryptionKey != null) { encryptionCipher = HiveAesCipher(base64Url.decode(encryptionKey!)); } await Hive.initFlutter('auth'); await Hive.openBox(_hiveBoxName, encryptionCipher: encryptionCipher) .timeout(const Duration(seconds: 1)); } @override Future hasAccessToken() { return Future.value( Hive.box(_hiveBoxName).containsKey( supabasePersistSessionKey, ), ); } @override Future accessToken() { return Future.value( Hive.box(_hiveBoxName).get(supabasePersistSessionKey) as String?, ); } @override Future removePersistedSession() { return Hive.box(_hiveBoxName).delete(supabasePersistSessionKey); } @override Future persistSession(String persistSessionString) { // Flush after X amount of writes return Hive.box(_hiveBoxName) .put(supabasePersistSessionKey, persistSessionString); } } ``` -------------------------------- ### Create temporary access URLs for files Source: https://context7.com/supabase/supabase-flutter/llms.txt Generate single or multiple signed URLs for temporary access to files. Specify the file path and expiration time in seconds. ```dart final String url = await supabase.storage .from('private-docs') .createSignedUrl('reports/q1-2024.pdf', 60); print('Signed URL: $url'); ``` ```dart final List urls = await supabase.storage .from('private-docs') .createSignedUrls( ['reports/q1-2024.pdf', 'reports/q2-2024.pdf'], 300, // 5 minutes ); for (final u in urls) { print('${u.path}: ${u.signedUrl}'); } ``` -------------------------------- ### signInWithPassword Source: https://context7.com/supabase/supabase-flutter/llms.txt Log in with email or phone number and password. ```APIDOC ### `signInWithPassword` — Log in with email or phone ```dart final AuthResponse res = await supabase.auth.signInWithPassword( email: 'user@example.com', password: 's3cr3tP@ssw0rd', ); // Or via phone number final AuthResponse phoneRes = await supabase.auth.signInWithPassword( phone: '+15551234567', password: 's3cr3tP@ssw0rd', ); final String accessToken = res.session!.accessToken; print('Logged in as ${res.user!.email}'); ``` ``` -------------------------------- ### Manage Package Versions Source: https://github.com/supabase/supabase-flutter/blob/main/AGENTS.md Update version files and manage package versions, including generating changelogs, using Melos. ```bash # Update version.dart files for all packages melos run update-version # Version packages and generate changelogs (handled by melos) melos version ``` -------------------------------- ### Initialize Supabase Client for Standalone Dart Source: https://context7.com/supabase/supabase-flutter/llms.txt Use the `supabase` package (not `supabase_flutter`) for server-side Dart or Dart Edge functions. Always dispose the client when done in a short-lived context. ```dart import 'package:supabase/supabase.dart'; final supabase = SupabaseClient( 'https://xyzcompany.supabase.co', 'your-service-role-key', // use service role key server-side authOptions: const AuthClientOptions( authFlowType: AuthFlowType.pkce, ), ); // Always dispose when done in a short-lived context await supabase.dispose(); ``` -------------------------------- ### Download files from Supabase Storage Source: https://context7.com/supabase/supabase-flutter/llms.txt Download files from a bucket. Supports on-the-fly image transformations like resizing. ```dart final Uint8List data = await supabase.storage .from('avatars') .download('public/alice/avatar.png'); ``` ```dart final Uint8List thumb = await supabase.storage .from('avatars') .download( 'public/alice/avatar.png', transform: const TransformOptions( width: 100, height: 100, resize: ResizeMode.cover, ), ); ``` -------------------------------- ### Manage Package Dependencies Source: https://github.com/supabase/supabase-flutter/blob/main/AGENTS.md Upgrade all dependencies across packages or check for outdated dependencies using Melos commands. ```bash # Upgrade dependencies across all packages melos run upgrade # Check for outdated dependencies melos run outdated ``` -------------------------------- ### Listen to All Supabase Logs Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/README.md Configure a logger to listen to all Supabase logs and set a custom log level. Records with Level.INFO and above are printed to the console in debug mode. ```dart import 'package:logging/logging.dart'; final supabaseLogger = Logger('supabase'); supabaseLogger.level = Level.ALL; // custom log level filtering, default is Level.INFO supabaseLogger.onRecord.listen((record) { print('${record.level.name}: ${record.time}: ${record.message}'); }); ``` -------------------------------- ### Database: Full-Text Search Source: https://context7.com/supabase/supabase-flutter/llms.txt Demonstrates how to perform full-text searches on a specified column using `supabase.from().select().textSearch()`. Supports different search types and configurations. ```dart final results = await supabase .from('documents') .select() .textSearch('content', 'flutter supabase', config: 'english', type: TextSearchType.websearch); print('Found ${results.length} documents'); ``` -------------------------------- ### Create temporary access URLs Source: https://context7.com/supabase/supabase-flutter/llms.txt Generates temporary, signed URLs for accessing files in a bucket. Useful for granting time-limited access to private files. ```APIDOC ## `createSignedUrl` / `createSignedUrls` — Temporary access URLs ### Description Generates temporary, signed URLs for accessing files in a bucket. Useful for granting time-limited access to private files. ### Method `createSignedUrl` (for a single file) `createSignedUrls` (for multiple files) ### Endpoint `supabase.storage.from('').createSignedUrl('', ) `supabase.storage.from('').createSignedUrls(, )` ### Parameters #### Path Parameters - **bucket_name** (string) - Required - The name of the storage bucket. - **path** (string) - Required - The path to the file within the bucket. - **paths_list** (List) - Required (for `createSignedUrls`) - A list of file paths. - **expires_in_seconds** (int) - Required - The duration in seconds for which the URL will be valid. ### Request Example ```dart // Single signed URL valid for 60 seconds final String url = await supabase.storage .from('private-docs') .createSignedUrl('reports/q1-2024.pdf', 60); print('Signed URL: $url'); // Multiple signed URLs at once final List urls = await supabase.storage .from('private-docs') .createSignedUrls( ['reports/q1-2024.pdf', 'reports/q2-2024.pdf'], 300, // 5 minutes ); for (final u in urls) { print('${u.path}: ${u.signedUrl}'); } ``` ### Response #### Success Response (200) - **url** (string) - The signed URL for the file (for `createSignedUrl`). - **urls** (List) - A list of objects containing the path and signed URL for each file (for `createSignedUrls`). Each `SignedUrl` object has: - **path** (string) - The original path of the file. - **signedUrl** (string) - The generated signed URL. ``` -------------------------------- ### Define Wrapper Libraries Source: https://github.com/supabase/supabase-flutter/blob/main/packages/supabase_flutter/example/windows/flutter/CMakeLists.txt Compiles the C++ wrapper libraries required for plugins and the main application runner. ```cmake # === Wrapper === list(APPEND CPP_WRAPPER_SOURCES_CORE "core_implementations.cc" "standard_codec.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") list(APPEND CPP_WRAPPER_SOURCES_PLUGIN "plugin_registrar.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") list(APPEND CPP_WRAPPER_SOURCES_APP "flutter_engine.cc" "flutter_view_controller.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") # Wrapper sources needed for a plugin. add_library(flutter_wrapper_plugin STATIC ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ) apply_standard_settings(flutter_wrapper_plugin) set_target_properties(flutter_wrapper_plugin PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(flutter_wrapper_plugin PROPERTIES CXX_VISIBILITY_PRESET hidden) target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) target_include_directories(flutter_wrapper_plugin PUBLIC "${WRAPPER_ROOT}/include" ) add_dependencies(flutter_wrapper_plugin flutter_assemble) # Wrapper sources needed for the runner. add_library(flutter_wrapper_app STATIC ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_APP} ) apply_standard_settings(flutter_wrapper_app) target_link_libraries(flutter_wrapper_app PUBLIC flutter) target_include_directories(flutter_wrapper_app PUBLIC "${WRAPPER_ROOT}/include" ) add_dependencies(flutter_wrapper_app flutter_assemble) ```