brunch

You can make anything
by writing

C.S.Lewis

by 이승현 Jul 27. 2016

Firebase #04

Storage

Firebase Storage


Firebase Storage is built for app developers who need to store and serve user-generated content, such as photos or videos.

(Firebase Storage는 사진이나 동영상 같은 사용자 제작 콘텐츠를 저장하고 제공해야 하는 앱 개발자들을 위해 만들어졌습니다.)


Firebase Storage provides secure file uploads and downloads for your Firebase apps, regardless of network quality.

(Firebase Storage는 네트워크 품질과 관계없이, Firebase 앱을 위해 보안 파일 업로드 및 다운로드를 제공합니다.)


You can use it to store images, audio, video, or other user-generated content.

(이미지, 오디오, 비디오 또는 사용자 제작 콘텐츠를 이용할 수 있습니다.)


Firebase Storage is backed by Google Cloud Storage, a powerful, simple, and cost-effective object storage service.

(Firebase Storage는 Google Cloud Storage에 의해 백업되고, 강력하고, 단순하고, 비용적으로 효율적인 저장 서비스입니다.)


https://firebase.google.com/docs/storage/

https://www.youtube.com/watch?list=PLl-K7zZEsYLmOF_07IayrTntevxtbUxDL&v=_tyjqozrEPY




Key functions

Robust
Firebase Storage는 네트워크 품질에 관계없이 업로드와 다운로드를 수행합니다. 업로드와 다운로드는 강력하고, 멈췄을 때 재시작하고, 사용자의 시간과 대역폭을 절약합니다.

Secure
Firebase Storage는 Firebase Authentication과 통합하여 간단하고 직관적인 인증을 개발자들에게 제공합니다. 파일 이름, 사이즈, 콘텐츠 타입 그리고 다른 메타데이터를 기반으로한 접근을 허용하기 위해 선언적인 보안 모델을 사용할 수 있습니다.

Scalable
Firebase Storage는 Google Cloud Storage를 통해 petabyte 규모로 백업됩니다. 프로토타입에서 부터 프로덕션 타입까지 동일한 인프라를 이용하여 여유롭게 성장해 나가세요.




Storage 시작



https://firebase.google.com/docs/storage/android/start

https://firebase.google.com/docs/reference/android/com/google/firebase/storage/package-summary



1. google-service.json 추가

#01 구성 파일 복사

Android studio에서 프로젝트 보기로 전환하여 프로젝트 루트 디렉터리를 표시하세요.

다운로드한 google-service.json 파일을 Android 앱 모듈 루트 디렉터리로 이동하세요.


2. plugin 추가

#02 Project build.gradle에 추가
buildscript {
    ...
    dependencies {
        ...
        classpath 'com.google.gms:google-services:3.0.0'
    }
}
#03 app build.gradle에 추가
apply plugin: 'com.android.application'

...

dependencies {
    ...
    compile 'com.google.firebase:firebase-storage:9.2.1'
    compile 'com.google.firebase:firebase-auth:9.2.1'
}

apply plugin: 'com.google.gms.google-services'

"firebase-core:9.2.1" 이 컴파일되지 않을 때는 아래와 같이 Google Play service 31 버전으로 업데이트해주세요.

https://brunch.co.kr/@oemilk/26


3. Firebase Storage Object 생성


파일들은 Firebase Storage bucket에 저장됩니다.

bucket안에 있는 이 파일들은 로컬 하드 디스크에 있는 파일 시스템이나 Firebase Realtime Database에 있는 데이터처럼 계층적 구조로 표시됩니다.

mFirebaseStorage = FirebaseStorage.getInstance();


4. StorageReference Object 생성


파일에 대한 참조를 만들면, 앱은 파일에 접근할 수 있습니다.

이런 참조들은 데이터를 업로드, 다운로드 하거나 메타데이터를 업데이트 또는 파일을 삭제할 때 이용할 수 있습니다.

참조는 특정 파일이나 계층에서 더 높은 레벨을 가리킬 수 있습니다.

참조는 클라우드에서 파일을 가리키는 것으로 생각할 수 있습니다.

참조들은 가볍기 때문에, 필요만큼 많이 생성할 수 있습니다.

또한 여러 작업에 재사용할 수 있습니다.

참조들은 Firebase app에서 getReferenceFromUrl 함수를 호출하고 "gs://<your-firebase-storage-bucket>. " 형태의 URL을 전달하여 URLgetFirebaseStorage 서비스로부터 생성됩니다.

private final String REFERENCE_URL = "gs://your-firebase-storage-bucket";

mStorageReference = mFirebaseStorage.getReferenceFromUrl(REFERENCE_URL);




Rule


기본적으로, Firebase Storage bucket은 파일을 다운로드하거나 업로드 할 때 Firebase Authenticaion을 요구합니다.

Firebase Storage Security Rules을 바꿔서 인증없이 접근하도록 할 수 있습니다.

기본 Google App Engine 앱과 Firebase는 이 bucket을 공유하므로, 공용 접근을 구성하는 것은 새로 업로드된 App Engine뿐만 아니라 공개적으로 접근할 수 있는 파일을 만들 수 있습니다.

인증을 설정할 때 다시 Storage bucket에 대한 접근을 제한해야 합니다.

아직 인증을 설정하지 않아 접근 권한을 Public으로 바꿔서 인증없이 접근할 수 있도록 했습니다.

#01 Firebase console - Storage - 규칙



Download Files


Firebase Storage는 Firebase에서 제공되고 관리되는 Google Cloud Storage bucket을 통해 쉽고 빠르게 파일들을 다운로드할 수 있도록 합니다.


1. Upload a file on Firebase Console


#01 Firebase Storage
#02 Add new folder
#03 Add new file


2. Create a Reference


private final String REFERENCE_URL = "gs://your-firebase-storage-bucket";
private final String DOWNLOAD_FILE_NAME = "image/firebase-discs.png";

mStorageReference = mFirebaseStorage.getReferenceFromUrl(REFERENCE_URL);
mDownloadStorageReference = mStorageReference.child(DOWNLOAD_FILE_NAME);


3. Download in memory


getBytes() 함수를 이용하여 파일을 byte[]에 다운로드합니다.

가장 쉬운 파일 다운로드 방법이나, 파일 콘텐츠 전체를 메모리에 반드시 로드 해야 합니다.

만약 앱의 가용 메모리보다 파일이 더 클 경우, 충돌이 일어날 수 있습니다.

메모리 이슈를 방지하기 위해, getBytes()는 다운로드 byte의 최대 사이즈를 정해야 합니다.

앱이 다룰수 있는 최대 사이즈나 다른 다운로드 함수를 이용하여 최대 사이즈를 설정해야 합니다.

#01 Download in memory
   final long ONE_MEGABYTE = 1024 * 1024;
   mDownloadStorageReference.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
      @Override
      public void onSuccess(byte[] bytes) {
         // onSuccess
      }
   }).addOnFailureListener(new OnFailureListener() {
      @Override
      public void onFailure(@NonNull Exception e) {
         // onFailure
      }
   });


4. Download to a local file


getFile() 함수는 곧바로 로컬 기기에 파일을 다운로드 합니다.

오프라인 상태에서 파일에 접근하기 원하거나 다른 앱과 파일을 공유하기 원한다면 이 방법을 쓰세요.

getFile()은 다운로드를 관리하고 상태를 관찰할 수 있는 DownloadTask를 반환합니다.

#01 Download to a local file
   try {
      File localFile = File.createTempFile("images", "jpg");
      mDownloadStorageReference.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
         @Override
         public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
            // onSuccess
         }
      }).addOnFailureListener(new OnFailureListener() {
         @Override
         public void onFailure(@NonNull Exception e) {
            // onFailure
         }
      });
   } catch (IOException e) {
      // exception
   }


5. Get a download uri


이미 URL을 기반으로 다운 받았거나, 단지 공유를 위해 URL을 원할 때, storage reference의 getDownload() 함수를 호출하여 파일의 다운로드 URL을 얻을 수 있습니다.

#01 Get a download uri
   mDownloadStorageReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
      @Override
      public void onSuccess(Uri uri) {
         // onSuccess uri
      }
   }).addOnFailureListener(new OnFailureListener() {
      @Override
      public void onFailure(@NonNull Exception e) {
         // onFailure
      }
   });





Upload Files


Firebase Storage는 Firebase에서 제공되고 관리되는 Google Cloud Storage bucket을 통해 쉽고 빠르게 파일들을 업로드할 수 있도록 합니다.


1. Create a Reference


private final String REFERENCE_URL = "gs://your-firebase-storage-bucket";
private final String UPLOAD_FILE_NAME = "upload.jpg";

mStorageReference = mFirebaseStorage.getReferenceFromUrl(REFERENCE_URL);
mUploadStorageReference= mStorageReference.child(UPLOAD_FILE_NAME );


2. Upload from data in memory


putData() 함수는 Firebase Storage에 가장 쉽게 파일을 업로드하는 방법입니다.

putData()는 byte[]를 가져와 업로드를 관리하고 상태를 관찰하는 UploadTask를 반환합니다.

putData()는 파일의 콘텐츠 전체를 메모리에 한번 올리기 때문에, 적은 메모리를 이용하도록 putStream()이나 putFile()을 이용할 때 주의해야 합니다.

#01 Upload from data in memory
mImageView.setDrawingCacheEnabled(true);
mImageView.buildDrawingCache();
Bitmap bitmap = mImageView.getDrawingCache();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] data = byteArrayOutputStream.toByteArray();

UploadTask uploadTask = mUploadStorageReference.putBytes(data);
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
   @Override
   public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
      // onSuccess
   }
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
   @Override
   public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
      double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
      // onProgress
   }
}).addOnPausedListener(new OnPausedListener<UploadTask.TaskSnapshot>() {
   @Override
   public void onPaused(UploadTask.TaskSnapshot taskSnapshot) {
      // onPaused
   }
}).addOnFailureListener(new OnFailureListener() {
   @Override
   public void onFailure(@NonNull Exception e) {
      // onFailure
   }
});
#01 Uploaded image file


3. Upload from a stream


putStream() 함수는 Firebase Storage에 파일을 업로드하는 가장 다목적으로 쓰이는 방법입니다.

putStream() 함수는 InputStream을 가져와 업로드를 관리하고 상태를 관찰하는 UploadTask를 반환합니다.

#01 Upload from a stream
try {
   InputStream inputStream = new FileInputStream(new File(FILE_PATH));
   UploadTask uploadTask = mUploadStorageReference.putStream(inputStream);
   uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
      @Override
      public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
         // onSuccess
      }
   }).addOnFailureListener(new OnFailureListener() {
      @Override
      public void onFailure(@NonNull Exception e) {
         // onFailure
      }
   });
} catch (FileNotFoundException e) {
   // Exception
}


4. Upload from a local file


putFile() 함수를 이용하여 사진이나 비디오같은 기기의 로컬 파일들을 업로드할 수 있습니다.

putFile() 함수는 File을 가져와 업로드를 관리하고 상태를 관찰하는 UploadTask를 반환합니다.

#01 Upload from a local file
Uri file = Uri.fromFile(new File(FILE_PATH));

// Add File Metadata
StorageMetadata storageMetadata = new StorageMetadata.Builder()
      .setContentType("image/jpg").build();

UploadTask uploadTask = mUploadStorageReference.putFile(file, storageMetadata);
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
   @Override
   public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
      // onSuccess
   }
}).addOnFailureListener(new OnFailureListener() {
   @Override
   public void onFailure(@NonNull Exception e) {
       // onFailure
   }
});


5. Update File Metadata


파일을 업로드할 때, 메타데이터도 같이 포함할 수 있습니다.

이 메타데이터는 이름, 크기, 콘텐츠타입(MIME 타입)같은 전형적인 파일 메타데이터 속성들을 포함하고 있습니다.

putFile() 함수는 자동으로 File 확장자를 통해 MIME 타입을 추론하나, 자동으로 감지된 타입을 새로 지정한 contentType으로 바꿀 수 있습니다.

contenType을 제공하지 않고 Firebase Storage가 파일 확장자로부터 추론할 수 없다면, Firebase Storage는 application/octet-stream을 이용할 것입니다.

파일이 완벽하게 업로드된 후, updateMetadata() 함수를 이용하여 언제든지 메타데이터를 업데이트할 수 있습니다.

#01 Update File Metadata
StorageMetadata storageMetadata = new StorageMetadata.Builder()
      .setContentType("image/jpg")
      .setCustomMetadata("custom meta key", "custom meta value")
      .build();

mUploadStorageReference.updateMetadata(storageMetadata)
      .addOnCompleteListener(new OnCompleteListener<StorageMetadata>() {
         @Override
         public void onComplete(@NonNull Task<StorageMetadata> task) {
            // onComplete
         }
      }).addOnFailureListener(new OnFailureListener() {
   @Override
   public void onFailure(@NonNull Exception e) {
      // onFailure
   }
});
#01 Uploaded custom metadata





Delete Files


1. Delete a File


파일을 삭제하기 위해, 먼저 referenct를 만들고 delete() 함수를 호출하세요.

#01 Delete a File
mUploadStorageReference.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
   @Override
   public void onSuccess(Void aVoid) {
      // onSuccess
   }
}).addOnFailureListener(new OnFailureListener() {
   @Override
   public void onFailure(@NonNull Exception e) {
      // onFailure
   }
});




Sample


https://github.com/oemilk/firebase




브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari