기타/Flutter

Flutter supabase 연결하기

남하욱 2024. 7. 29. 06:29

supabase는 간단하게 백앤드 서버를 구축할 수 있는 백앤드 서비스 플랫폼이다.

이 포스팅은 supabase 사용방법보다는 맨 처음 supabase와 flutter 연결 설정하는 것에 초점을 둠

 

flutter와 supabase를 연결하기 위해서는 다음 과정을 거친다.

supabase

  1. supabase 사이트 접속 후 로그인
  2. supabase에서 project 생성
  3. supabase의 project에서 table 생성
  4. table의 policy 설정

flutter

  1. pubspec.yaml 파일에 의존성 추가
  2. terminal에서 package 설치
  3. dart 파일에 supabase-flutter package import
  4. supabase에서 project의 API key 값들 얻어옴
  5. supabase initialize
  6. supabase client 개체 선언
  7. 선언한 supabase client 개체를 통해 원하는 동작에서 insert, select, delete 등으로 DB data와 통신

https://supabase.com/docs/guides/getting-started/quickstarts/flutter


In Supabase Site

 

supabase 사이트 접속 후 로그인

 

Supabase | The Open Source Firebase Alternative

Build production-grade applications with a Postgres database, Authentication, instant APIs, Realtime, Functions, Storage and Vector embeddings. Start for free.

supabase.com

아이디 만들어 접속하라고 하는데, 나는 github 아이디로 하였다.

 

Project 만들기

- 새로운 project를 만듦

- 이때, 이름과 password 설정해주고, 한국으로 region 설정하고 create 한다

 

Table 만들기

- Table을 만들고, 왼쪽에 있는 카테고리에서 "Table Editor" 클릭

- "Create a new table" 버튼 클릭

- Name에 원하는 table 이름 넣기

- columns에 자신이 원하는 속성명과 type을 설정해준다 (예시에서는 id와 name)

- 나머지는 건들지 않고 "save" 버튼을 눌러 table을 생성한다.

※ (primary key, foreign key 등의 DB 개념은 이 포스팅에서 다루지 않는다)

 

policy 설정

- 그냥 이렇게 table만 만들면 flutter 등의 외부 tool에서 DB와 통신할 수 없다.

- policy에서 가능하도록 설정한 기능들만 사용할 수 있다.

- 이 글에서는 All로 설정하여 다 되도록 한다

- 왼쪽 선택 창들에서 스크롤을 내려 "ALL"이라 되어 있는 칸을 누른다

- using 칸 안에 있는 내용을 지우고, true로 바꾸고 save한다


In Flutter Project

 

pubspec.yaml 파일에 의존성 추가

- supabase를 사용할 flutter project 안에서 "pubspec.yaml" 파일에 접근

- 쭉 내리면 "dependencies"라고 되어 있는 곳이 있는데, 여기에 아래 스크린샷과 같이 추가하고 저장

 

terminal에서 package 설치

- 안드로이드 스튜디오의 flutter project에서 왼쪽 아래의 terminal 창을 연다

- terminal이 뜨면 "flutter pub get"을 입력하여 package를 설치한다

 

supabase-flutter package import

flutter의 main.dart에 package를 import 한다.


supabase project의 API key 값들 얻어와서 initialize & Client 선언

- supabase project 안에서 왼쪽 카테고리의 Home을 클릭

- Project API 안에 있는 project URL, API Key 둘 다 복사해서 flutter의 main.dart에 변수로 저장

- main문 비동기 함수로 선언하고 initialize 함수 실행

- supabase client 개체 선언

 

선언한  supabase client 개체로 DB data와 통신

- 이제 supabase를 이용하여 DB Table의 값들과 통신할 수 있다

- insert, select, delete 등 많은 방법이 있지만 이 포스팅에서 다루지는 않는다


확인용 실행 코드

- 제대로 연결 됐는지 확인용 코드

- main.dart에 전체 복사 붙여넣기

- 6,7 Line의 API Key 값만 위에 했던 대로 찾아와서 넣고 실행

import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

int count = 0;

const supabaseUrl = 'YOUR URL';
const supabaseKey = "YOUR KEY";

Future<void> main() async {

  await Supabase.initialize(url: supabaseUrl, anonKey: supabaseKey);

  runApp(MyApp());
}

// Get a reference your Supabase client
final supabase = Supabase.instance.client;

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Test',
      home: MyHomePage(),
    );
  }
}
class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final TextEditingController _nameController = TextEditingController();
  List<dynamic> _data = [];

  @override
  void initState() {
    super.initState();
    _fetchData();
  }

  Future<void> _insertData() async {
    final response = await supabase
        .from('user')
        .insert([{'id':count, 'name': _nameController.text}])
        .select();

    if (response.isNotEmpty) {
      print('Data inserted successfully: ${response}');
      _fetchData();
      count++;
    } else {
      print('Error inserting data');
    }
  }

  Future<void> _fetchData() async {
    final response = await supabase
        .from('user')
        .select()
        .order('id', ascending: true);

    if (response.isNotEmpty) {
      setState(() {
        _data = response;
      });
    } else {
      print('Error fetching data');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Supabase Flutter Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(
              controller: _nameController,
              decoration: InputDecoration(labelText: 'Name'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _insertData,
              child: Text('Insert Data'),
            ),
            SizedBox(height: 20),
            Expanded(
              child: ListView.builder(
                itemCount: _data.length,
                itemBuilder: (context, index) {
                  final item = _data[index];
                  return ListTile(
                    title: Text('ID: ${item['id']}'),
                    subtitle: Text('Name: ${item['name']}'),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

 

제대로 실행되면 다음과 같은 화면이 나온다

- 현재 table의 모든 data들 밑에 출력

- insert 버튼 누르면 name 칸에 넣은 값으로 Table에 data insert