[flutter] 플러터를 사용하여 클라우드 스토리지와의 비동기 파일 전송 방법

플러터는 Google에서 개발한 UI 프레임워크로 다양한 플랫폼에서 동작하는 앱을 만들 수 있습니다. 플러터는 비동기 작업 처리를 위해 asyncawait를 사용하여 간편하게 파일 전송 기능을 구현할 수 있습니다. 이번 포스트에서는 플러터를 사용하여 클라우드 스토리지와의 파일 전송을 비동기적으로 처리하는 방법을 알아보겠습니다.

1. Firebase 연동

플러터에서 클라우드 스토리지와의 파일 전송을 구현하기 위해선 먼저 Firebase를 프로젝트에 연동해야 합니다. Firebase는 Google에서 제공하는 클라우드 기반 개발 플랫폼으로, 다양한 서비스를 제공합니다. Firebase를 연동하려면 Firebase 콘솔에서 프로젝트를 생성하고, google-services.json 파일을 프로젝트에 추가해야 합니다.

2. Firebase Storage 설정

Firebase 프로젝트를 생성하고 google-services.json 파일을 추가한 뒤에는 Firebase Storage를 설정해야 합니다. Firebase Storage는 클라우드 기반의 파일 저장소로, 파일 업로드/다운로드, 이미지 리사이징 등 다양한 기능을 제공합니다. Storage를 사용하기 위해선 Firebase 프로젝트의 build.gradle 파일에 아래의 종속성을 추가해야 합니다.

dependencies {
  implementation 'com.google.firebase:firebase-storage:19.2.0'
}

3. 파일 업로드 구현

Firebase Storage와의 파일 업로드를 구현하기 위해선 먼저 파일을 선택하고 업로드할 수 있는 기능을 추가해야 합니다. 이를 위해 Flutter의 file_picker 패키지를 사용하겠습니다.

프로젝트의 pubspec.yaml 파일에 file_picker 패키지를 추가합니다.

dependencies:
  file_picker: ^3.0.0

이제 파일 선택 버튼을 추가하고, 사용자가 파일을 선택하면 해당 파일을 업로드하는 기능을 구현해보겠습니다.

import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;

class FileUploadScreen extends StatefulWidget {
  @override
  _FileUploadScreenState createState() => _FileUploadScreenState();
}

class _FileUploadScreenState extends State<FileUploadScreen> {
  String? _filePath;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('파일 업로드'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: _selectFile,
              child: Text('파일 선택'),
            ),
            if (_filePath != null) Text('선택한 파일: $_filePath'),
            if (_filePath != null)
              ElevatedButton(
                onPressed: _uploadFile,
                child: Text('파일 업로드'),
              ),
          ],
        ),
      ),
    );
  }

  Future<void> _selectFile() async {
    FilePickerResult? result = await FilePicker.platform.pickFiles();

    if (result != null) {
      setState(() {
        _filePath = result.files.single.path;
      });
    }
  }

  Future<void> _uploadFile() async {
    if (_filePath == null) return;

    firebase_storage.FirebaseStorage storage =
        firebase_storage.FirebaseStorage.instance;

    String fileName = _filePath!.split('/').last;
    firebase_storage.Reference ref =
        storage.ref().child('uploads/$fileName');

    await ref.putFile(new File(_filePath!));

    setState(() {
      _filePath = null;
    });
    
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('파일이 업로드되었습니다.')),
    );
  }
}

위의 코드는 파일 선택 버튼을 추가하고, 사용자가 파일을 선택하면 _selectFile 메서드가 호출됩니다. _selectFile 메서드는 file_picker 패키지를 이용하여 파일을 선택하고, 선택한 파일의 경로를 _filePath 변수에 저장합니다.

파일을 선택한 후에는 “파일 업로드” 버튼이 나타나고, 사용자가 이 버튼을 누르면 _uploadFile 메서드가 호출됩니다. _uploadFile 메서드에서는 선택한 파일을 Firebase Storage에 업로드합니다. 업로드된 파일은 uploads 폴더 안에 저장되며, 파일 이름은 선택한 파일의 마지막 경로 구성 요소로 지정됩니다.

파일 업로드가 완료되면 _filePath 변수를 초기화하고, 업로드 성공 메시지를 보여주는 SnackBar를 표시합니다.

4. 결론

위의 코드를 통해 플러터를 사용하여 클라우드 스토리지와의 비동기 파일 전송 기능을 구현하는 방법을 알아보았습니다. Firebase를 사용하면 플러터 앱에서 손쉽게 파일 업로드/다운로드 기능을 구현할 수 있으며, 파일 선택 및 업로드 과정이 비동기적으로 처리되기 때문에 사용자 경험을 향상시킬 수 있습니다.

Firebase와 플러터의 조합은 다양한 앱 개발에 활용할 수 있는 강력한 도구입니다. Firebase Storage 외에도 Firebase의 다른 서비스를 사용하여 앱을 더욱 기능을 향상시킬 수 있으니, 관심 있는 분들은 Firebase 공식 문서를 참고해보시기 바랍니다.