Skip to Content
Другие инструменты и адаптерыАдаптеры баз данныхСупабаза

Адаптер Supabase Postgres

Пакет tracelet_supabase предоставляет встраиваемый адаптер для синхронизации фоновых расположений непосредственно с Supabase Postgres с помощью функции RPC Postgres или Edge Function Supabase.

Установка

Добавьте адаптер в pubspec.yaml:

flutter pub add tracelet_supabase

Этот адаптер использует supabase_flutter. Вы должны инициализировать клиент Supabase перед его использованием.

Как это работает

Адаптер подключается к энергосберегающему собственному механизму синхронизации HTTP Tracelet: buildHttpConfig создает HttpConfig, указывающий на конечную точку REST Supabase — либо /rest/v1/rpc/<function> (RPC), либо /functions/v1/<function> (Edge Function) — с установленными для вас заголовками apikey и Authorization: Bearer <token>.

Поскольку синхронизация выполняется на собственном движке, пакеты загружаются с экспоненциальной задержкой и постановкой в ​​очередь в автономном режиме даже при принудительном закрытии. При 401 configureTokenRefresh обновляет сеанс Supabase — на переднем плане и в изолированном фоновом режиме — и повторяет попытку. Вы указываете ровно одну цель: rpcFunction или edgeFunction.

Настройка и конфигурация

Создайте таблицу и функцию приема

Создайте таблицу для получения местоположений, включите RLS и добавьте функцию Postgres, которая вставляет входящий пакет. Tracelet отправляет пакет объектов местоположения, поэтому функция принимает массив jsonb:

-- Table CREATE TABLE public.locations ( id uuid DEFAULT gen_random_uuid() PRIMARY KEY, user_id uuid REFERENCES auth.users NOT NULL DEFAULT auth.uid(), latitude double precision NOT NULL, longitude double precision NOT NULL, accuracy double precision, speed double precision, timestamp timestamptz NOT NULL, is_moving boolean, created_at timestamptz DEFAULT now() ); ALTER TABLE public.locations ENABLE ROW LEVEL SECURITY; CREATE POLICY "Users insert their own locations" ON public.locations FOR INSERT WITH CHECK (auth.uid() = user_id); -- RPC function: receives the batch as a jsonb array and inserts each row. -- (The exact field names come from Tracelet's sync payload — see the -- Tracelet Sync docs for the payload schema.) CREATE OR REPLACE FUNCTION public.insert_tracelet_locations(payload jsonb) RETURNS void LANGUAGE sql SECURITY INVOKER AS $$ INSERT INTO public.locations (latitude, longitude, accuracy, speed, timestamp, is_moving) SELECT (e->'coords'->>'latitude')::double precision, (e->'coords'->>'longitude')::double precision, (e->'coords'->>'accuracy')::double precision, (e->'coords'->>'speed')::double precision, (e->>'timestamp')::timestamptz, (e->>'is_moving')::boolean FROM jsonb_array_elements(payload) AS e; $$;

Предпочитаете более индивидуальную обработку (проверку, разветвление, обогащение)? Вместо этого разверните Supabase Edge Function и передайте ее имя как edgeFunction — адаптер отправит пакет POST в /functions/v1/<name>.

Инициализировать Супабазу

Инициализируйте клиент Supabase в main.dart:

import 'package:supabase_flutter/supabase_flutter.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Supabase.initialize( url: 'https://xyzcompany.supabase.co', anonKey: 'public-anon-key', ); runApp(const MyApp()); }

Настройте обновление токена и создайте конфигурацию HTTP

Вызовите configureTokenRefresh() один раз, создайте HttpConfig, предназначенный для вашего RPC (или Edge Function), и передайте его Tracelet.ready:

import 'package:tracelet_supabase/tracelet_supabase.dart'; import 'package:tracelet/tracelet.dart'; const supabaseUrl = 'https://xyzcompany.supabase.co'; const supabaseAnonKey = 'public-anon-key'; // 1. Keep the Supabase session token fresh in the background (resolves 401s). await TraceletSupabase.configureTokenRefresh(anonKey: supabaseAnonKey); // 2. Build the native HTTP config. Provide EITHER rpcFunction OR edgeFunction. final httpConfig = TraceletSupabase.buildHttpConfig( supabaseUrl: supabaseUrl, anonKey: supabaseAnonKey, rpcFunction: 'insert_tracelet_locations', // ...or: edgeFunction: 'tracelet-ingest' // autoSync: true, batchSync: true, maxBatchSize: 250 are the defaults ); // 3. Start Tracelet with the adapter's HTTP config. await Tracelet.ready(Config( geo: const GeoConfig(distanceFilter: 50), http: httpConfig, )); await Tracelet.start();

Прикрепление пользовательских метаданных

Чтобы пометить каждое местоположение бизнес-данными (например, driver_id или trip_id), используйте setRouteContext() — он проходит с каждым местоположением через очередь SQLite и включается в полезную нагрузку, которую получает ваша функция:

await Tracelet.setRouteContext(RouteContext( taskId: 'order_123', custom: {'trip_id': 'trip_456'}, ));

Производительность

Синхронизация выполняется через пакетный механизм Tracelet, поэтому накопившиеся автономные точки сбрасываются пакетами (по умолчанию maxBatchSize: 250), а не по одному запросу на точку. В сочетании с массовой вставкой Postgres внутри вашего RPC это обеспечивает эффективное высокочастотное отслеживание (например, точка каждые 10 м) как для батареи устройства, так и для передачи данных туда и обратно.