😇
Supabaseからログインしているユーザーのデータを取得
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