Android에서 Cloud Storage로 파일 다운로드

Cloud Storage for Firebase 앱을 사용하면 쉽고 빠르게 다운로드할 수 있습니다. Cloud Storage의 파일 Firebase가 제공하고 관리하는 버킷입니다.

참조 만들기

파일을 다운로드하려면 먼저 다운로드할 파일을 가리키는 Cloud Storage 참조를 만듭니다.

루트에 하위 경로를 추가하여 참조를 만들 수 있습니다. Cloud Storage 버킷을 만들거나 기존 버킷의 참조를 만들 수 있습니다. Cloud Storage의 객체를 참조하는 gs:// 또는 https:// URL입니다.

Kotlin+KTX

// Create a storage reference from our app
val storageRef = storage.reference

// Create a reference with an initial file path and name
val pathReference = storageRef.child("images/stars.jpg")

// Create a reference to a file from a Google Cloud Storage URI
val gsReference = storage.getReferenceFromUrl("gs://bucket/images/stars.jpg")

// Create a reference from an HTTPS URL
// Note that in the URL, characters are URL escaped!
val httpsReference = storage.getReferenceFromUrl(
    "https://firebasestorage.googleapis.com/b/bucket/o/images%20stars.jpg",
)

Java

// Create a storage reference from our app
StorageReference storageRef = storage.getReference();

// Create a reference with an initial file path and name
StorageReference pathReference = storageRef.child("images/stars.jpg");

// Create a reference to a file from a Google Cloud Storage URI
StorageReference gsReference = storage.getReferenceFromUrl("gs://bucket/images/stars.jpg");

// Create a reference from an HTTPS URL
// Note that in the URL, characters are URL escaped!
StorageReference httpsReference = storage.getReferenceFromUrl("https://firebasestorage.googleapis.com/b/bucket/o/images%20stars.jpg");

파일 다운로드

참조가 만들어졌으면 Cloud Storage에서 파일을 다운로드할 수 있습니다. 이를 위해 getBytes() 또는 getStream()를 호출합니다. 파일을 다운로드하려는 경우 getDownloadUrl()를 사용하여 다운로드 URL을 가져올 수 있습니다.

메모리에 다운로드

getBytes() 메서드로 파일을 byte[]에 다운로드합니다. 이는 파일을 다운로드하는 가장 쉬운 방법이지만 메모리에 전체 파일 콘텐츠를 로드해야 합니다. 따라서 앱의 가용 메모리보다 큰 파일을 요청하면 앱이 다운됩니다. 메모리 문제를 방지하기 위해 getBytes()는 다운로드할 최대 바이트 수를 지정합니다. 최대 크기를 앱에서 처리할 수 있는 크기로 설정하거나 다른 다운로드 방법을 사용하세요.

Kotlin+KTX

var islandRef = storageRef.child("images/island.jpg")

val ONE_MEGABYTE: Long = 1024 * 1024
islandRef.getBytes(ONE_MEGABYTE).addOnSuccessListener {
    // Data for "images/island.jpg" is returned, use this as needed
}.addOnFailureListener {
    // Handle any errors
}

Java

StorageReference islandRef = storageRef.child("images/island.jpg");

final long ONE_MEGABYTE = 1024 * 1024;
islandRef.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
    @Override
    public void onSuccess(byte[] bytes) {
        // Data for "images/island.jpg" is returns, use this as needed
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle any errors
    }
});

로컬 파일로 다운로드

getFile() 메서드는 파일을 로컬 기기로 직접 다운로드합니다. 사용자가 오프라인 상태에서도 파일에 액세스해야 하거나 다른 앱에서 파일을 공유해야 하는 경우 이 방법을 사용하세요. getFile()은 다운로드를 관리하고 다운로드 상태를 모니터링하는 데 사용할 수 있는 DownloadTask를 반환합니다.

Kotlin+KTX

islandRef = storageRef.child("images/island.jpg")

val localFile = File.createTempFile("images", "jpg")

islandRef.getFile(localFile).addOnSuccessListener {
    // Local temp file has been created
}.addOnFailureListener {
    // Handle any errors
}

Java

islandRef = storageRef.child("images/island.jpg");

File localFile = File.createTempFile("images", "jpg");

islandRef.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
        // Local temp file has been created
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle any errors
    }
});

다운로드를 직접 관리하는 방법은 다운로드 관리를 참조하세요.

URL을 통해 데이터 다운로드

이미 URL 기반의 다운로드 인프라를 갖추고 있거나 공유할 URL이 있으면 다음을 호출하여 파일의 다운로드 URL을 가져올 수 있습니다. Cloud Storage 참조의 getDownloadUrl() 메서드

Kotlin+KTX

storageRef.child("users/me/profile.png").downloadUrl.addOnSuccessListener {
    // Got the download URL for 'users/me/profile.png'
}.addOnFailureListener {
    // Handle any errors
}

Java

storageRef.child("users/me/profile.png").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
    @Override
    public void onSuccess(Uri uri) {
        // Got the download URL for 'users/me/profile.png'
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle any errors
    }
});

FirebaseUI로 이미지 다운로드

FirebaseUI는 단순하고 맞춤설정 가능하고 프로덕션 환경에서 즉시 사용할 수 있는 기본 모바일 바인딩을 제공하며, 이 바인딩을 사용하면 상용구 코드를 제거하고 Google의 권장사항을 도입할 수 있습니다. FirebaseUI를 사용하여 다음을 수행할 수 있습니다. 이미지를 빠르고 쉽게 다운로드, 캐시, 표시 Google과의 통합을 통해 Cloud Storage에서 글라이드.

먼저 app/build.gradle에 FirebaseUI를 추가합니다.

dependencies {
    // FirebaseUI Storage only
    implementation 'com.firebaseui:firebase-ui-storage:7.2.0'
}

그런 다음 Cloud Storage에서 ImageView에 직접 이미지를 로드할 수 있습니다.

Kotlin+KTX

// Reference to an image file in Cloud Storage
val storageReference = Firebase.storage.reference

// ImageView in your Activity
val imageView = findViewById<ImageView>(R.id.imageView)

// Download directly from StorageReference using Glide
// (See MyAppGlideModule for Loader registration)
Glide.with(context)
    .load(storageReference)
    .into(imageView)

Java

// Reference to an image file in Cloud Storage
StorageReference storageReference = FirebaseStorage.getInstance().getReference();

// ImageView in your Activity
ImageView imageView = findViewById(R.id.imageView);

// Download directly from StorageReference using Glide
// (See MyAppGlideModule for Loader registration)
Glide.with(context)
        .load(storageReference)
        .into(imageView);

활동 수명 주기 변화 처리

대화상자 표시, 화면 회전 등으로 활동 수명 주기가 변화해도 다운로드는 백그라운드에서 계속됩니다. 연결된 리스너도 연결된 채로 유지됩니다. 이 때문에 활동이 중지된 후 리스너가 호출되면 예기치 않은 결과가 나타날 수 있습니다.

활동 범위와 함께 리스너를 구독하면 활동이 중지될 때 리스너가 자동으로 등록 취소되므로 문제가 해결됩니다. 그런 다음 활동이 다시 시작될 때 getActiveDownloadTasks 메서드를 사용하여 여전히 실행 중이거나 최근에 완료된 다운로드 작업을 가져올 수 있습니다.

아래 예시에서는 이 방법과 함께 사용된 스토리지 참조 경로를 유지하는 방법을 보여 줍니다.

Kotlin+KTX

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)

    // If there's a download in progress, save the reference so you can query it later
    outState.putString("reference", storageRef.toString())
}

override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)

    // If there was a download in progress, get its reference and create a new StorageReference
    val stringRef = savedInstanceState.getString("reference") ?: return

    storageRef = Firebase.storage.getReferenceFromUrl(stringRef)

    // Find all DownloadTasks under this StorageReference (in this example, there should be one)
    val tasks = storageRef.activeDownloadTasks

    if (tasks.size > 0) {
        // Get the task monitoring the download
        val task = tasks[0]

        // Add new listeners to the task using an Activity scope
        task.addOnSuccessListener(this) {
            // Success!
            // ...
        }
    }
}

Java

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    // If there's a download in progress, save the reference so you can query it later
    if (mStorageRef != null) {
        outState.putString("reference", mStorageRef.toString());
    }
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    // If there was a download in progress, get its reference and create a new StorageReference
    final String stringRef = savedInstanceState.getString("reference");
    if (stringRef == null) {
        return;
    }
    mStorageRef = FirebaseStorage.getInstance().getReferenceFromUrl(stringRef);

    // Find all DownloadTasks under this StorageReference (in this example, there should be one)
    List<FileDownloadTask> tasks = mStorageRef.getActiveDownloadTasks();
    if (tasks.size() > 0) {
        // Get the task monitoring the download
        FileDownloadTask task = tasks.get(0);

        // Add new listeners to the task using an Activity scope
        task.addOnSuccessListener(this, new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(FileDownloadTask.TaskSnapshot state) {
                // Success!
                // ...
            }
        });
    }
}

오류 처리

다운로드 시 오류가 발생하는 이유는 파일이 없는 경우, 사용자에게 파일 액세스 권한이 없는 경우 등 다양합니다. 오류에 대한 자세한 내용은 문서의 오류 처리 섹션을 참조하세요.

전체 예시

다음은 오류 처리가 포함된 다운로드에 대한 전체 예시입니다.

Kotlin+KTX

storageRef.child("users/me/profile.png").getBytes(Long.MAX_VALUE).addOnSuccessListener {
    // Use the bytes to display the image
}.addOnFailureListener {
    // Handle any errors
}

Java

storageRef.child("users/me/profile.png").getBytes(Long.MAX_VALUE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
    @Override
    public void onSuccess(byte[] bytes) {
        // Use the bytes to display the image
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle any errors
    }
});

메타데이터를 가져오거나 업데이트할 수도 있습니다. Cloud Storage에 저장된 파일용