tracelet_supabase パッケージは、Postgres RPC 関数 または Supabase エッジ関数 を介して、バックグラウンドの場所を Supabase Postgres に直接同期するためのドロップイン アダプターを提供します。
インストール
アダプターを pubspec.yaml に追加します。
flutter pub add tracelet_supabaseこのアダプターは supabase_flutter を使用します。 Supabase クライアントを使用する前に初期化する必要があります。
仕組み
このアダプターは、Tracelet のバッテリー効率の高い ネイティブ HTTP 同期エンジンに接続されます。buildHttpConfig は、apikey ヘッダーと Authorization: Bearer <token> ヘッダーが設定された、Supabase REST エンドポイント (/rest/v1/rpc/<function> (RPC) または /functions/v1/<function> (エッジ関数)) を指す HttpConfig を生成します。
同期はネイティブ エンジンで実行されるため、アプリが強制終了された場合でも、指数バックオフとオフライン キューを使用してバッチがアップロードされます。 401 では、configureTokenRefresh は Supabase セッションを (フォアグラウンドおよびヘッドレス バックグラウンド分離で) 更新し、再試行します。 正確に 1 つのターゲットを指定します: 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 エッジ関数 をデプロイし、その名前を edgeFunction として渡します。アダプターはバッチを /functions/v1/<name> に POST します。
スーパーベースの初期化
main.dart で Supabase クライアントを初期化します。
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() を 1 回呼び出し、RPC (またはエッジ関数) を対象とする HttpConfig を構築し、それを 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() を使用します。setRouteContext() は SQLite キューを介して各場所を移動し、関数が受け取るペイロードに含まれます。
await Tracelet.setRouteContext(RouteContext(
taskId: 'order_123',
custom: {'trip_id': 'trip_456'},
));パフォーマンス
同期は Tracelet のバッチ エンジンを通じて実行されるため、オフライン ポイントのバックログは、ポイントごとに 1 つのリクエストではなく、バッチ (デフォルトは maxBatchSize: 250) でフラッシュされます。 RPC 内での Postgres の一括挿入と組み合わせることで、デバイスのバッテリーとデータベースのラウンドトリップの両方で高頻度の追跡 (例: 10 m ごとのポイント) の効率が維持されます。