본문 바로가기
Flutter/Snippet

플러터 앱에 Firebase를 이용하여 사용자 정보 관리 기능 추가하기

by Maccrey Coding 2024. 8. 29.
반응형

 

Flutter로 앱을 개발할 때, 기본적인 인증 정보 외에 추가적인 사용자 정보를 관리해야 할 때가 있습니다.

예를 들어, 사용자의 닉네임, 생일, 프로필 사진 등의 정보를 관리하려면 유저 모델을 정의하고 이를 기반으로 데이터를 처리해야 합니다.

이번 포스팅에서는 Flutter에서 유저 모델을 통해 추가 유저 정보를 관리하는 방법을 단계별로 설명하겠습니다.

 

1. 유저 모델 정의하기

유저 모델(User Model)은 사용자의 데이터를 구조화하여 관리하는 데 도움을 줍니다.

Dart에서 클래스를 사용해 유저 모델을 정의할 수 있습니다. 예를 들어, 사용자의 UID, 이메일, 닉네임, 프로필 사진 URL 등을 포함하는 모델을 정의해보겠습니다.

class UserModel {
  final String uid;
  final String email;
  final String? nickname;
  final String? profileImageUrl;
  final DateTime? birthday;

  UserModel({
    required this.uid,
    required this.email,
    this.nickname,
    this.profileImageUrl,
    this.birthday,
  });

  // Firestore에서 데이터를 가져와 UserModel로 변환하는 메서드
  factory UserModel.fromMap(Map<String, dynamic> data, String uid) {
    return UserModel(
      uid: uid,
      email: data['email'] ?? '',
      nickname: data['nickname'],
      profileImageUrl: data['profileImageUrl'],
      birthday: data['birthday'] != null ? (data['birthday'] as Timestamp).toDate() : null,
    );
  }

  // UserModel을 Firestore에 저장할 수 있는 Map 형태로 변환하는 메서드
  Map<String, dynamic> toMap() {
    return {
      'email': email,
      'nickname': nickname,
      'profileImageUrl': profileImageUrl,
      'birthday': birthday != null ? Timestamp.fromDate(birthday!) : null,
    };
  }
}

2. Firebase Firestore에 유저 정보 저장 및 불러오기

유저 정보를 Firebase Firestore에 저장하고 불러오기 위해 Firebase 패키지를 사용합니다.

firebase_auth와 cloud_firestore 패키지를 pubspec.yaml 파일에 추가합니다.

dependencies:
  firebase_auth: latest_version
  cloud_firestore: latest_version

이제 Firestore에 유저 정보를 저장하고 불러오는 서비스를 작성해보겠습니다.

2.1 Firestore 서비스 작성

lib/services/firestore_service.dart 파일을 생성하여 Firestore와 상호작용하는 로직을 구현합니다.

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:your_project_name/models/user_model.dart';

class FirestoreService {
  final FirebaseFirestore _db = FirebaseFirestore.instance;

  // Firestore에 유저 정보 저장
  Future<void> saveUser(UserModel user) async {
    await _db.collection('users').doc(user.uid).set(user.toMap());
  }

  // Firestore에서 유저 정보 불러오기
  Future<UserModel?> getUser(String uid) async {
    DocumentSnapshot doc = await _db.collection('users').doc(uid).get();
    if (doc.exists) {
      return UserModel.fromMap(doc.data() as Map<String, dynamic>, doc.id);
    }
    return null;
  }

  // 유저 정보 업데이트
  Future<void> updateUser(UserModel user) async {
    await _db.collection('users').doc(user.uid).update(user.toMap());
  }
}

2.2 유저 로그인 시 정보 저장

사용자가 처음 로그인할 때, Firebase Authentication에서 제공하는 기본 정보와 함께 Firestore에 유저 정보를 저장합니다.

아래는 로그인 처리 후 Firestore에 유저 정보를 저장하는 코드입니다.

import 'package:firebase_auth/firebase_auth.dart';
import 'package:your_project_name/models/user_model.dart';
import 'package:your_project_name/services/firestore_service.dart';

class AuthService {
  final FirebaseAuth _auth = FirebaseAuth.instance;
  final FirestoreService _firestoreService = FirestoreService();

  Future<void> signInWithEmailAndPassword(String email, String password) async {
    UserCredential result = await _auth.signInWithEmailAndPassword(email: email, password: password);
    User? user = result.user;

    if (user != null) {
      // Firestore에 유저가 이미 존재하는지 확인
      UserModel? existingUser = await _firestoreService.getUser(user.uid);

      if (existingUser == null) {
        // Firestore에 유저 정보가 없다면 새로운 유저 정보 저장
        UserModel newUser = UserModel(
          uid: user.uid,
          email: user.email!,
          nickname: "New User",  // 기본 닉네임 설정
        );
        await _firestoreService.saveUser(newUser);
      }
    }
  }
}

3. 유저 정보 업데이트 UI 구현

사용자가 자신의 정보를 수정할 수 있는 UI를 구현해보겠습니다.

프로필 화면에서 사용자가 닉네임이나 프로필 사진을 변경할 수 있도록 합니다.

import 'package:flutter/material.dart';
import 'package:your_project_name/models/user_model.dart';
import 'package:your_project_name/services/firestore_service.dart';

class ProfileScreen extends StatefulWidget {
  final UserModel user;

  ProfileScreen({required this.user});

  @override
  _ProfileScreenState createState() => _ProfileScreenState();
}

class _ProfileScreenState extends State<ProfileScreen> {
  final _formKey = GlobalKey<FormState>();
  late String _nickname;

  @override
  void initState() {
    super.initState();
    _nickname = widget.user.nickname ?? '';
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Edit Profile'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: Column(
            children: [
              TextFormField(
                initialValue: _nickname,
                decoration: InputDecoration(labelText: 'Nickname'),
                onSaved: (value) {
                  _nickname = value ?? '';
                },
              ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: () async {
                  if (_formKey.currentState?.validate() ?? false) {
                    _formKey.currentState?.save();
                    // 유저 정보 업데이트
                    UserModel updatedUser = widget.user.copyWith(nickname: _nickname);
                    await FirestoreService().updateUser(updatedUser);
                    ScaffoldMessenger.of(context).showSnackBar(
                      SnackBar(content: Text('Profile Updated')),
                    );
                  }
                },
                child: Text('Save'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

4. Firebase에서 유저 정보 관리 시 고려 사항

  • 데이터 보안: Firestore에서 유저 정보를 관리할 때는 보안 규칙을 설정하여 비인가자가 접근할 수 없도록 해야 합니다.
  • 실시간 업데이트: Firestore의 실시간 기능을 활용하여 다른 사용자가 유저 정보를 업데이트하면 자동으로 반영되도록 할 수 있습니다.
  • 오프라인 지원: Firestore는 오프라인에서도 데이터를 사용할 수 있도록 캐싱을 지원합니다. 이를 통해 네트워크 상태와 관계없이 유저 정보를 관리할 수 있습니다.

이 글에서는 Flutter에서 유저 모델을 통해 추가 유저 정보를 관리하는 방법을 소개했습니다. 유저 모델을 사용하면 구조화된 데이터를 쉽게 관리할 수 있으며, Firestore와 연동하여 유저 정보를 저장하고 불러오는 작업을 간편하게 처리할 수 있습니다. 이를 통해 앱에서 더욱 풍부한 사용자 경험을 제공할 수 있습니다.

공감과 댓글은 저에게 큰 힘이 됩니다.

Starting Google Play App Distribution! "Tester Share" for Recruiting 20 Testers for a Closed Test.

 

Tester Share [테스터쉐어] - Google Play 앱

Tester Share로 Google Play 앱 등록을 단순화하세요.

play.google.com

반응형