ดาวน์โหลดไฟล์ด้วย Cloud Storage บน Android

Cloud Storage สำหรับ Firebase ช่วยให้คุณดาวน์โหลดไฟล์จากที่เก็บ ข้อมูล Cloud Storage ที่ Firebase จัดเตรียมและจัดการโดย Firebase ได้อย่างรวดเร็วและง่ายดาย

สร้างข้อมูลอ้างอิง

หากต้องการดาวน์โหลดไฟล์ ขั้นแรก ให้สร้างการอ้างอิง Cloud Storage ไปยังไฟล์ที่คุณต้องการดาวน์โหลด

คุณสามารถสร้างข้อมูลอ้างอิงได้โดยเพิ่มเส้นทางลูกต่อท้ายรากของที่เก็บข้อมูล Cloud Storage ของคุณ หรือคุณสามารถสร้างข้อมูลอ้างอิงจาก gs:// หรือ https:// URL ที่มีอยู่ซึ่งอ้างอิงออบเจ็กต์ใน Cloud Storage ก็ได้

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() หากคุณต้องการดาวน์โหลดไฟล์ด้วยไลบรารีอื่น คุณสามารถรับ URL ดาวน์โหลดด้วย getDownloadUrl()

ดาวน์โหลดในหน่วยความจำ

ดาวน์โหลดไฟล์เป็น byte[] ด้วยเมธอด getBytes() นี่เป็นวิธีที่ง่ายที่สุดในการดาวน์โหลดไฟล์ แต่จะต้องโหลดเนื้อหาทั้งหมดของไฟล์ของคุณลงในหน่วยความจำ หากคุณขอไฟล์ที่มีขนาดใหญ่กว่าหน่วยความจำที่มีอยู่ของแอป แอปของคุณจะขัดข้อง เพื่อป้องกันปัญหาหน่วยความจำ 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 ดาวน์โหลดไฟล์ได้โดยการเรียกใช้เมธอด getDownloadUrl() ในการอ้างอิง Cloud Storage

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 คุณสามารถดาวน์โหลด แคช และแสดงรูปภาพจาก Cloud Storage ได้อย่างรวดเร็วและง่ายดายโดยใช้การผสานรวมกับ Glide

ขั้นแรก เพิ่ม FirebaseUI ให้กับ app/build.gradle :

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 ได้ด้วย