Firebase Storage 소개
개요
Firebase Storage는 구글의 Firebase 플랫폼에 속하는 강력한 클라우드 기반 파일 저장 서비스입니다.
이 서비스는 앱 개발자들이 사용자로부터 받은 사진, 동영상, 오디오 파일과 같은 대용량 파일을 안전하고 효율적으로 저장하고 관리할 수 있도록 설계되었습니다.
Firebase Storage는 Google Cloud Storage 위에 구축되어, Google의 클라우드 인프라의 확장성과 보안성을 그대로 활용할 수 있습니다.

주요 특징
- 확장성:
- 사용자의 증가나 데이터의 증가에 따라 자동으로 확장되므로, 어떤 규모의 프로젝트에도 적합합니다.
- 보안:
- Firebase Authentication과 함께 사용하면 사용자 인증 정보에 따라 파일 접근을 제어할 수 있어, 강력한 보안 체계를 구축할 수 있습니다.
- 효율적인 데이터 전송:
- 네트워크 상태가 불안정하거나 변동적인 환경에서도 데이터 전송이 중단되었을 경우, 이어서 전송할 수 있는 기능을 제공합니다.
- 통합 개발 환경:
- Firebase의 다른 서비스들과의 뛰어난 통합성을 자랑하여, 애널리틱스, 데이터베이스, 인증 등 다양한 기능을 함께 사용하여 앱 개발의 효율성을 높일 수 있습니다.
앞선 Firebase 포스팅들
- (Flutter-기초 강의) 18. Flutter에서 Firebase 사용하기 (소개 및 프로젝트 설정)
- (Flutter-기초 강의) 19. Firebase Database(Realtime Database) 사용하기
- (Flutter-기초 강의) 20. Firebase 인증(Authentication) 사용하기 – Google 인증 , Email인증
Firebase Storage SDK 소개
Firebase Storage SDK는 Flutter, Android, iOS, Web 등 다양한 플랫폼에서 Firebase Storage 서비스를 사용할 수 있도록 제공하는 라이브러리입니다.
각 플랫폼마다 SDK의 구체적인 구현은 다르지만, 기본적인 기능은 비슷합니다.
주요 클래스
- FirebaseStorage:
- Firebase Storage 서비스의 진입점입니다.
- 이 클래스를 통해 스토리지 인스턴스를 관리할 수 있습니다.
FirebaseStorage.instance
를 사용하여 인스턴스에 접근할 수 있습니다.
- StorageReference:
- 저장된 파일을 참조하는 객체입니다.
- 파일 경로를 나타내며, 파일 업로드, 다운로드, 메타데이터 조회 및 삭제 작업을 수행할 수 있습니다.
FirebaseStorage
인스턴스에서ref()
함수를 호출하여 생성할 수 있습니다.
- UploadTask:
- 파일 업로드를 비동기적으로 처리하는 작업입니다.
putFile
,putData
,putBlob
함수를 통해 업로드 작업을 시작할 수 있으며, 업로드 상태를 모니터링하고 결과를 처리할 수 있습니다.
- DownloadTask:
- 파일 다운로드 작업을 비동기적으로 처리합니다.
StorageReference
의writeToFile
또는getData
메서드를 사용하여 다운로드 작업을 시작할 수 있습니다.
- TaskSnapshot:
- 업로드 또는 다운로드 작업의 상태와 결과를 포함합니다.
- 작업이 완료된 후, 이 클래스의 인스턴스를 통해 작업 결과에 접근할 수 있습니다.
주요 함수
- uploadFile():
- 파일을 업로드합니다.
import 'package:firebase_storage/firebase_storage.dart'; // Create Firebase Storage Instance final storage = FirebaseStorage.instance; // 파일 업로드 Future<void> uploadFile(String filePath, String fileName) async { // Create reference object final ref = storage.ref().child(fileName); // Upload File final task = ref.putFile(File(filePath)); // Check Progress task.snapshotEvents.listen((snapshot) { print('Progress: ${snapshot.bytesTransferred} / ${snapshot.totalBytes}'); }); // Complete await task.whenComplete(() => print('Upload complete')); } // Use Example uploadFile('path/to/image.jpg', 'image.jpg');
- downloadFile():
- 파일을 다운로드합니다.
// Download File Future<void> downloadFile(String fileName) async { // Create Object final ref = storage.ref().child(fileName); // Download file final task = ref.writeToFile(File('path/to/file')); // Check download progress task.snapshotEvents.listen((snapshot) { print('Progress: ${snapshot.bytesTransferred} / ${snapshot.totalBytes}'); }); // Complete download await task.whenComplete(() => print('Download complete')); } // Use Example downloadFile('image.jpg');
- getDownloadURL():
- 파일의 다운로드 URL을 가져옵니다.
// Get File URL Future<String> getFileUrl(String fileName) async { // Create reference object final ref = storage.ref().child(fileName); // Get Download URL final url = await ref.getDownloadURL(); return url; } // Use Example final url = await getFileUrl('image.jpg'); print(url);
- deleteFile():
- 파일을 삭제합니다.
// Delete File Future<void> deleteFile(String fileName) async { // Create reference object final ref = storage.ref().child(fileName); // Delete File await ref.delete(); print('File deleted'); } // Use Example deleteFile('image.jpg');
- listAll():
- 버킷에 저장된 모든 파일 목록을 가져옵니다.
// Get All File List Stored in the bucket Future<List<StorageReference>> listAll() async { // Create reference object final ref = storage.ref(); // Get All File list final list = await ref.listAll(); // List up all files for (final item in list.items) { print('File: ${item.name}'); } return list.items; } // Use Example listAll();
- list():
- 버킷에 저장된 파일 목록을 쿼리합니다.
// Query file list stored in the bucket Future<List<StorageReference>> list() async { // Create reference object final ref = storage.ref(); // Setting query param final query = Query.orderBy('name'); // query to get list final list = await ref.list(query); // display items for (final item in list.items) { print('File: ${item.name}'); } return list.items; } // Use example list();
사용하기
본 예제는 앞선 포스팅 예제에서 사용하던 _7_firebase 프로젝트에 이어서 사용합니다.
1. Console에서 Storage 서비스 활성화
firebase console에서 Storage 섹션으로 이동합니다.
[Build] -> [Storage] -> (Get Started) 를 클릭후 인증 방법 및 생성할 Location을 설정합니다.



2. Firebase Storage 사용을 위한 패키지 설치
Firebase Storage를 사용하기 위한 패키지들을 추가합니다.
$ flutter pub add firebase_core firebase_storage
사용하고자 하는 곳에 다음을 import 합니다.
import 'package:firebase_storage/firebase_storage.dart';
3. Memo 파일 생성
MemoDetailPage
에서 Memo를 파일 형태로 만들기 위해 path_provider
패키지를 추가합니다.
$ flutter pub add path_provider
path_provider
패키지를 import합니다.
import 'package:path_provider/path_provider.dart';
Application Document 폴더에 Memo의 Title과 Contents를 파일형태로 저장하는 함수를 정의합니다.
Future<File> _writeMemoToLocalFile(String fileName, String content) async { final directory = await getApplicationDocumentsDirectory(); final file = File('${directory.path}/$fileName'); // Write the file (File Name and Content) final fileContent = 'Title: $fileName\n\nContents: $content'; return file.writeAsString(fileContent); }
4. Memo 파일 저장 및 업로드
앞서 정의한 _writeMemoToLocalFile()
를 이용하여, 파일 형태로 저장하고,
FirebaseStorage.instance.ref()
를 이용하여 Firebase Storage 서비스에 putFile()
를 이용해 업로드 하는 함수를 정의합니다.
위 동작의 결과를 ScaffoldMessager
의 showSnackBar()
를 통해 표시합니다.
Future<void> saveMemoToFileAndUpload() async { final dateTime = DateTime.now(); final fileName = '${dateTime.toIso8601String()}_memo.txt'; final localFile = await _writeMemoToLocalFile(fileName, widget.memo.content); try { await FirebaseStorage.instance.ref('memos/$fileName').putFile(localFile); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Save memo as file and upload success!')), ); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error occured: $e')), ); } }
Floating Button을 클릭하여 위 함수를 수행합니다.
floatingActionButton: FloatingActionButton( onPressed: () { saveMemoToFileAndUpload(); }, child: const Icon(Icons.save_alt), ),
결과

