😇

Supabaseからログインしているユーザーのデータを取得

2024/05/29に公開

Tips💡

Supabaseから特定のユーザーの情報だけ取得をしたい。ログインしているユーザーのプロフィール情報を取得したユースケースがあるとします。どのようなコードを書けばできるというと、 FutureProviderを使用して、 uuidが一致するユーザーの情報を取得するクエリを実行することです。

参考にしたクエリ

Retrieve one row of data
Retrieves only one row from the result. Result must be one row (e.g. using limit), otherwise this will result in an error.

1 行のデータを取得します
結果から 1 行のみを取得します。結果は 1 行である必要があります (例: limit を使用)。そうでない場合はエラーが発生します。


final data = await supabase
  .from('cities')
  .select('name, country_id')
  .single();

[riverpodのコード]
async/awaitをつけて、非同期書にすることで、Supabaseからログインしているユーザーのデータを1行だけ取得できるようになりました。

import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:workstream_prod/core/logger/logger.dart';
part 't_user_future_provider.g.dart';


Future<Map<String, dynamic>> tUserFuture(TUserFutureRef ref) async {
  try {
    final supabase = Supabase.instance.client;
    final userId = supabase.auth.currentUser!.id;
    final response = await supabase.from('t_user').select().eq('uuid', userId).single();
    logger.d('🍎fetch data: $response');
    return response;
  } on Exception catch (e) {
    logger.d('😇t_user error: $e');
    rethrow;
  }
}

雑なコードかも知れないですが、これでView側に特定のデータだけ表示することができました。

class ProfilePage extends HookConsumerWidget {
  const ProfilePage({super.key});
  
  Widget build(BuildContext context, WidgetRef ref) {
    final tUser = ref.watch(tUserFutureProvider);

    return Scaffold(
      backgroundColor: AppColor.grey,
      body: ScreenUtilInit(
        designSize: ScreenUtil.defaultSize,
        minTextAdapt: true,
        splitScreenMode: true,
        builder: (_, child) => tUser.when(
          data: (d) => Text(d['user_name']),
          error: (e, s) => Text('Error'),
          loading: () => IndicatorComponent(),
        )
      ),
    );
  }
}

新しいriverpodの書き方だと、when -> switch に変わるさそうなので、修正してみました。 Riverpod3からは、switchになる話を聞いたことがあります(^^;;

class ProfilePage extends HookConsumerWidget {
  const ProfilePage({super.key});
  
  Widget build(BuildContext context, WidgetRef ref) {
    final tUser = ref.watch(tUserFutureProvider);

    return Scaffold(
      backgroundColor: AppColor.grey,
      body: ScreenUtilInit(
        designSize: ScreenUtil.defaultSize,
        minTextAdapt: true,
        splitScreenMode: true,
        builder: (_, child) => switch(tUser) {
           AsyncData(:final value) => Text(value['uuid']),
           AsyncError(:final error) => Text('Error: $error'),
          _=> const IndicatorComponent(),
        },
      ),
    );
  }
}

最後に

昨日やっててて上手くいかなかったのですが単純に、 thenメソッドがないとのことらしいので、awaitをつけると、returnで返している値のエラーが消えたのでそれだけ解消すれば良かったという単純な話でした😅

Discussion