[Flutter] 스나이퍼팩토리 Flutter 중급과정 (15)

GONG·2023년 5월 24일
0
post-thumbnail

Firebase Storage

  • Firebase에서 제공하는 저장공간 (데이터 클라우드)

  • 이미지, 파일, 동영상 등 멀티미디어나 바이너리를 저장하여 사용할 수 있음

  • 업로드하고, 다운로드 URL을 사용하는 방식

  • reference라는 ‘참조’ 방식인데, 폴더 경로를 생각할 수 있음

    final storageRef = FirebaseStorage.instance.ref();
  • 콘솔에서 storage 사용 설정

    • 빌드 > storage > 시작하기
    • 일단 테스트모드
    • 위치는 전에 프로젝트 생성할 때 설정햇던 위치로 뜸
    • 짜잔

파일 업로드

  • 경로를 먼저 설정한 뒤에 저장할 수 있음
  • putFile이라는 메소드를 활용
    final storageRef = FirebaseStorage.instance.ref('images/mountains.jpg');
    await storageRef.putData(data);

파일 다운로드

  • 특별한 경우가 아닌 이상 파일 다운로드는 URL로 처리할 수 있음
    final storageRef = FirebaseStorage.instance.ref('images/myImage.jpg');
    var fileUrl = await storageRef.getDownloadUrl();

코드 작성

  • 35일차 코드에 main_controller 추가
  • main_controller.dart
    import 'dart:io';
    
    import 'package:firebase_storage/firebase_storage.dart';
    import 'package:get/get.dart';
    import 'package:firebase_auth/firebase_auth.dart';
    import 'package:image_picker/image_picker.dart';
    
    import '../model/profile.dart';
    import 'auth_controller.dart';
    
    class MainController extends GetxController {
      final RxList images = [].obs;
    
      User? get user => Get.find<AuthController>().user.value;
      Profile? get profile => Get.find<AuthController>().profile.value;
    
      fetchImages() async {
        var ref = FirebaseStorage.instance.ref('/images');
        var res = await ref.listAll();
        images.clear();
        for (var item in res.items) {
          var url = await item.getDownloadURL();
          images.add(url);
        }
      }
    
      uploadImage(XFile file) {
        var ref = FirebaseStorage.instance.ref('/images/${file.name}.png');
        ref.putFile(File(file.path)).then((p0) {
          fetchImages();
        });
      }
    }
  • main_page.dart 수정
    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    import 'package:image_picker/image_picker.dart';
    
    import '../controller/auth_controller.dart';
    import '../controller/main_controller.dart';
    
    class MainPage extends GetView<MainController> {
      const MainPage({Key? key}) : super(key: key);
    
      
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Obx(() => SingleChildScrollView(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Row(
                    children: [
                      CircleAvatar(
                        radius: 36,
                        backgroundImage: controller.user!.photoURL != null
                            ? NetworkImage(controller.user!.photoURL!)
                            : null,
                      ),
                      Expanded(
                        child: Card(
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.stretch,
                            children: [
                              Text('혈액형: ${controller.profile?.bloodtype ?? 'null'}'),
                              Text('직업: ${controller.profile?.job ?? 'null'}'),
                              Text('mbti: ${controller.profile?.mbti ?? 'null'}'),
                            ],
                          ),
                        ),
                      ),
                    ],
                  ),
                  ...controller.images.map((e) => Image.network(e)).toList(),
                  TextButton(
                    onPressed: () async {
                      var picker = ImagePicker();
                      var res = await picker.pickImage(source: ImageSource.gallery);
                      if (res != null) {
                        controller.uploadImage(res);
                      }
                    },
                    child: Text('업로드')
                  )
                ],
              ),
            )),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () => Get.toNamed('edit/profile'),
            child: Icon(Icons.edit),
          ),
        );
      }
    }

유저 프로필 사진 등록

  1. imagepicker 킨다
  2. 이미지 고른다
  3. 스토리지 올린다
  4. 다운로드url 받고 그걸 updatePhotoURL에 올려야함

코드 작성

  • main_controller.dart 에 handleOnTap 메소드 추가
    handleOnTap() async {
        var picker = ImagePicker();
        var res = await picker.pickImage(source: ImageSource.gallery);
        if (res != null) {
          // 스토리지 올리기
          var ref = FirebaseStorage.instance.ref('profile/${user!.uid}');
          await ref.putFile(File(res.path));
          var downloadUrl = await ref.getDownloadURL();
          print(downloadUrl);
          // downloadUrl 받기
          user!.updatePhotoURL(downloadUrl);
        }
      }
  • main_page.dart 수정
    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    import 'package:image_picker/image_picker.dart';
    
    import '../controller/auth_controller.dart';
    import '../controller/main_controller.dart';
    
    class MainPage extends GetView<MainController> {
      const MainPage({Key? key}) : super(key: key);
    
      
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Obx(() => SingleChildScrollView(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  GestureDetector(
                    child: Container(
                      width: 150,
                      height: 150,
                      child: CircleAvatar(
                        radius: 36,
                        backgroundImage: controller.user!.photoURL != null
                            ? NetworkImage(controller.user!.photoURL!)
                            : null,
                      ),
                    ),
                    onTap: controller.handleOnTap,
                  ),
                  SizedBox(height: 16),
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      Text(controller.user!.displayName!),
                      Text(controller.user!.email!),
                    ],
                  ),
                ],
              ),
            )),
          ),
        );
      }
    }

36일차 끝~

profile
우와재밋다

0개의 댓글