본문 바로가기
CODE/Flutter

[Flutter] Supabase - Subscribe to Channel(구독) 사용하기

by Nuridal_class 2023. 12. 22.
728x90
728x90

 Supabasae - Subscribe to Channel 사용하기

이전 포스팅을 통해서 Stream을 사용해 데이터를 실시간으로 CRUD 해보았습니다
 

[Flutter] Supabase stream CRUD 해보기

Supabase stream CRUD 이전 포스팅에선 Supabase에서 실시간으로 데이터의 값을 확인하는 방법에 대해서 알아보았습니다 [Flutter, Supabase] Supabase RealTime Data 가져오기 RealTime Data 가져오기 이전 포스팅으로

nuridal-class.tistory.com

그런데 이전 글 말미에서 언급했듯이 왜? print를 했는데 값이 null이 나올까?
이 답에 대한 해답과 사용방법에 대해서 알아보도록 하겠습니다

 

Stream과  Subscribe의 차이점

결론 먼저 말씀드리면 Subscribe를 사용하지 않았기 때문에 print를 해도 null값이 반환되었습니다
그렇다면 Subscribe는 무엇이고 Stream과 차이점이 어떤 것인지 알아보겠습니다
👉 Subscribe 란?
데이터베이스란 채널을 구독하여 변경사항이 일어난 것을 실시간으로 감지한다는 의미인데요

쉽게 말해서 아래의 예시에서 countries란 테이블에
이벤트가 all 이니 모든 변경사항에 대해서 callback을 받겠다는 의미가 되겠습니다

supabase
    .channel('public:countries')
    .onPostgresChanges(
        event: PostgresChangeEvent.all,
        schema: 'public',
        table: 'countries',
        callback: (payload) {
          print('Change received: ${payload.toString()}');
        })
    .subscribe();​
이렇게 보면 둘의 차이점은 callback에 있는것을 볼 수 있습니다
즉, Stream은 말 그대로 db의 데이터를 뿌려주기만 하고 Subscribe는 뿌려준 데이터를 활용할 수 있단 말이 되겠습니다
그렇다면 어떻게 사용하는지 간단한 예제를 통해 알아보도록 하겠습니다

 

 supabase_subscribe_to_channel_view.dart

아래 코드 같이 todo table에 구독을 해놓으면 stream은 데이터 변화를 볼 수만 있었다면
이제는 변화된 데이터를 가지고 여러 가지로 활용을 할 수 있게 되었습니다
//📲 새롭게 추가된 코드만 작성되었습니다
//📲 전체코드는 github에서 확인가능합니다

  ...
  
  //📲 페이지로 왔을 때 구독을 초기 설정을 해주는 부분
  @override
  void initState() {
    todoSubscribe();
    super.initState();
  }

  ...
  
  //📲 실제적으로 구독을 하는 부분
  //📲 todo taable이란 채널에서 발생하는 모든 이벤트에 대해 
  //📲 eventHandler를 반환하겠다라는 함수
  void todoSubscribe() {
    supabase
        .channel('todos')
        .onPostgresChanges(
            event: PostgresChangeEvent.all,
            schema: 'public',
            table: 'todo',
            callback: eventHandler)
        .subscribe();
  }

  //📲 전체적인 payload를 print 하고
  //📲 insert, update, delete 이벤트를 분기점으로 잡아
  //📲 해당 이벤트 발생 시 snackbar를 나타나게 하는 함수
  void eventHandler(payload) {
    debugPrint('payload:${payload.toString()}');
    if (payload.eventType == PostgresChangeEvent.insert) {
      ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text(' ${payload.newRecord['todo']}이 추가되었습니다')));
    } else if ((payload.eventType == PostgresChangeEvent.update)) {
      ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text(' ${payload.newRecord['todo']}로 수정되었습니다')));
    } else if ((payload.eventType == PostgresChangeEvent.delete)) {
      ScaffoldMessenger.of(context)
          .showSnackBar(const SnackBar(content: Text('삭제되었습니다')));
    }
  }

  ...

 

 결과 화면

print를 하게 되면 아래와 같이 payload가 나오게 됩니다
아래의 예시는 update 이벤트가 발생했을 때에 log입니다

payload:PostgresChangePayload(schema: public, table: todo, commitTimestamp: 2023-12-22 00:20:55.398 Z, eventType: PostgresChangeEvent.update, newRow: {check: false, created_at: 2023-12-20T 02:04:21+00:00, id: 1, todo: 12 time}, oldRow: {id: 1}, errors: null)

flutter supabase subscribe insertflutter supabase subscribe updateflutter supabase subscribe delete
왼쪽부터 insert, update, delete 입니다

 추가로 확인해야 할 사항

이 데이터들을 더 활용하려면 update나 delete를 했을 때
oldRow에 다른 칼럼들의 데이터들도 나왔으면 좋겠지만 
기본 세팅으로는 primaryKey의 값만 나오는 듯합니다
이걸 해결하려면 Trigger란 것을 사용해야 하는데 더 연구를 해봐야 할 것 같습니다 😂

 

그래도 여기까지만 따라 하셔도 데이터를 활용하는 방법은 있을 거라 생각합니다
전체코드는 아래의 github에 올려두었습니다 
마음껏 사용하셔도 무관합니다!
 

GitHub - Jeoungeunseok/supabase: supabase connection and postgreSQL use

supabase connection and postgreSQL use. Contribute to Jeoungeunseok/supabase development by creating an account on GitHub.

github.com


이번 포스팅으로 Supabase의 Realtime을 확인하는 또 다른 방법인
Subscribe에 대해서 알아보았습니다
많은 분들에게 조금이라도 도움이 되었으면 좋겠습니다
그럼! 코딩이 쉬워지는 그날까지!!

728x90
300x250