본문 바로가기

Flutter/12 Clone 'Used Goods app'

[Flutter] Clone - 당근마켓22(userModel 구현)

이번에는 사용자 정보(userModel)를 실제 쓰고, 읽기를 구현해보겠습니다.

개발환경 : 윈도우11, 안드로이드 스튜디오, flutter 3.0.1

 

 

 

./src/repo/user_service.dart

 

import 'package:cloud_firestore/cloud_firestore.dart';

import '../constants/data_keys.dart';
import '../models/user_model.dart';

class UserService {

  // 싱글톤 디자인 패턴 ***************************************
  // 인스턴스가 한번만 생성되고, 2번째 생성시에는 처음 생성한 인스턴스를 리턴,
  static final UserService _userService = UserService._internal();
  factory UserService() => _userService;
  UserService._internal();
  // 싱글톤 디자인 패턴 ***************************************

  // 사용자 uid 를 기반으로 저장하고, uid 를 기반으로 저장된 정보가 있으면 skip, 
  Future createNewUser(Map<String, dynamic> json, String userKey) async {

    DocumentReference<Map<String, dynamic>> docRef =
    FirebaseFirestore.instance.collection(COL_USERS).doc(userKey);
    final DocumentSnapshot documentSnapshot = await docRef.get();

    // 사용자 정보가 없으면 생성함,
    if(!documentSnapshot.exists){
      await docRef.set(json);
    }
  }

  // 사용자 uid 를 이용하여 데이터 읽기,
  Future<UserModel1> getUserModel(String userKey) async {

    DocumentReference<Map<String, dynamic>> docRef =
    FirebaseFirestore.instance.collection(COL_USERS).doc(userKey);
    final DocumentSnapshot<Map<String, dynamic>> documentSnapshot = await docRef.get();

    // UserModel userModel = UserModel.fromSnapshot(documentSnapshot);
    UserModel1 userModel1 = UserModel1.fromJson(documentSnapshot.data()!);
    userModel1.reference = documentSnapshot.reference;
    // debugPrint('--------------------------------------------------');
    // debugPrint('documentSnapshot: ${documentSnapshot.id}');
    // debugPrint('documentSnapshot: ${documentSnapshot.reference}');

    return userModel1;
  }
}

 

 

 

./src/states/user_state.dart

 

class UserController extends GetxController {
  static UserController get to => Get.find();

  final _user = Rxn<User?>();
  final _userModel = Rxn<UserModel1?>();

  Rxn<User?> get user => _user;
  Rxn<UserModel1?> get userModel => _userModel;

  void initUser() {
    FirebaseAuth.instance.authStateChanges().listen((user) async {
      // user 정보가 변경되면, 호출됨,
      await _setNewUser(user);
      Get.offAllNamed('/');
    });
  }

  Future<void> _setNewUser(User? user) async {
    _user.value = user;

    // user 정보가 변경되면, 전화번호가 있어야만 호출됨,
    if (user != null && user.phoneNumber != null) {
      SharedPreferences prefs = await SharedPreferences.getInstance();
      String address = prefs.getString(SHARED_ADDRESS) ?? '';
      double lat = prefs.getDouble(SHARED_LAT) ?? 0;
      double lon = prefs.getDouble(SHARED_LON) ?? 0;
      String phoneNumber = user.phoneNumber!;
      String userKey = user.uid;
      debugPrint('get Address: [$address] [$lat] [$lon]');
      debugPrint('get phone&uid: [$phoneNumber] [$userKey]');
      logger.d('(initUser)user status - $user');

      // 기존 모델이 아닌 새로운 모델로 작업중, UserModel >> UserModel1
      UserModel1 userModel = UserModel1(
        userKey: userKey,
        phoneNumber: phoneNumber,
        address: address,
        lat: lat,
        lon: lon,
        geoFirePoint: GeoFirePoint(lat, lon),
        createdDate: DateTime.now().toUtc(),
      );

      // 사용자 정보가 없으면 생성함, 있으면 무시함,
      await UserService().createNewUser(userModel.toJson(), userKey);
      _userModel.value = await UserService().getUserModel(userKey);
      logger.d('(_userModel) - ${_userModel.toString()}');

    }
  }

  @override
  void onReady() {
    // TODO: implement onReady
    super.onReady();
    initUser();
    logger.d('(onReady)user status - $user');
  }
}

 

 

 

저장된 결과는 아래와 같습니다.