Flutter 앱에 Firebase Realtime Database 사용하기

Firebase의 Realtime Database는 NoSQL 클라우드 데이터베이스로, 모든 클라이언트에서 실시간으로 데이터가 동기화된다. 이번에는 Realtime Database(실시간 데이터베이스)를 이용해서 저장한 JSON 데이터를 Flutter 앱에서 리스트로 표시하는 기능을 구현해 본다.

Firebase에서 Realtime Database 만들기

실시간 데이터베이스 위치는 미국으로 한다.

실시간 데이터베이스 저장 위치를 선택한다
 실시간 데이터베이스 저장 위치를 선택한다

빠른 설정을 위해 테스트 모드로 선택한다.

보안 규칙은 잠금 모드와 테스트 모드 에서 선택한다
 보안 규칙은 잠금 모드와 테스트 모드 에서 선택한다

실시간 데이터베이스가 만들어지면 JSON 데이터를 직접 입력하거나 가져오기, 내보내기가 가능하다.

JSON 데이터를 직접 입력하거나 가져오기, 내보내기 할 수 있다
 JSON 데이터를 직접 입력하거나 가져오기, 내보내기 할 수 있다

테스트용 JSON 데이터 준비

Flutter 앱에서 테스트하기 위해 아래와 같이 JSON 데이터를 준비한다.

테스트를 위해 입력된 JSON 데이터
 테스트를 위해 입력된 JSON 데이터

Flutter 앱에서 Realtime Database 데이터 리스트로 표시

Flutter 앱의 main.dart 파일에서 Firebase core플러그인 및 firebase_database.dart, firebase_options.dart를 가져온다.

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';
import 'firebase_options.dart';

데이터를 적재할 수 있도록 Item 클래스를 작성한다.

class Item {
  final String key;
  final String title;
  final String desc;

  Item({required this.key, required this.title, required this.desc});

  factory Item.fromMap(String key, Map<String, dynamic> map) {
    return Item(
      key: key,
      title: map['title'] ?? '',
      desc: map['desc'] ?? '',
    );
  }
}

목록을 표시하는 페이지를 작성한다.

class ItemListPage extends StatefulWidget {
  @override
  _ItemListPageState createState() => _ItemListPageState();
}

class _ItemListPageState extends State<ItemListPage> {
  final databaseRef = FirebaseDatabase.instance.ref('items');
  List<Item> itemList = [];

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

  void _loadItems() async {
    final snapshot = await databaseRef.get();
    final items = <Item>[];

    if (snapshot.exists) {
      final data = Map<String, dynamic>.from(snapshot.value as Map);
      data.forEach((key, value) {
        items.add(Item.fromMap(key, Map<String, dynamic>.from(value)));
      });
    }

    setState(() {
      itemList = items;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('목록 보기')),
      body: ListView.builder(
        itemCount: itemList.length,
        itemBuilder: (context, index) {
          final item = itemList[index];
          return ListTile(
            title: Text(item.title),
            subtitle: Text(item.desc),
          );
        },
      ),
    );
  }
}

이제 코드를 빌드하여 실행하면, 다음과 같이 Realtime Database의 JSON 데이터를 목록 형태로 표시하게 된다.

Realtime Database의 JSON 데이터가 Flutter 앱의 리스트에 표시된 모습
 Realtime Database의 JSON 데이터가 Flutter 앱의 리스트에 표시된 모습

전체적인 코드는 다음과 같다.

import 'package:flutter/material.dart';

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';
import 'firebase_options.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: ItemListPage(),
    );
  }
}

class Item {
  final String key;
  final String title;
  final String desc;

  Item({required this.key, required this.title, required this.desc});

  factory Item.fromMap(String key, Map<String, dynamic> map) {
    return Item(
      key: key,
      title: map['title'] ?? '',
      desc: map['desc'] ?? '',
    );
  }
}

class ItemListPage extends StatefulWidget {
  @override
  _ItemListPageState createState() => _ItemListPageState();
}

class _ItemListPageState extends State<ItemListPage> {
  final databaseRef = FirebaseDatabase.instance.ref('items');
  List<Item> itemList = [];

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

  void _loadItems() async {
    final snapshot = await databaseRef.get();
    final items = <Item>[];

    if (snapshot.exists) {
      final data = Map<String, dynamic>.from(snapshot.value as Map);
      data.forEach((key, value) {
        items.add(Item.fromMap(key, Map<String, dynamic>.from(value)));
      });
    }

    setState(() {
      itemList = items;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('목록 보기')),
      body: ListView.builder(
        itemCount: itemList.length,
        itemBuilder: (context, index) {
          final item = itemList[index];
          return ListTile(
            title: Text(item.title),
            subtitle: Text(item.desc),
          );
        },
      ),
    );
  }
}

Leave a Comment