העלאת קבצים באמצעות Cloud Storage ב-Flutter

‫Cloud Storage for Firebase מאפשר להעלות קבצים במהירות ובקלות לקטגוריה של Cloud Storage שמוענקת ומנוהלת על ידי Firebase.

העלאת קבצים

כדי להעלות קובץ ל-Cloud Storage, קודם יוצרים הפניה לנתיב המלא של הקובץ, כולל שם הקובץ.

// Create a storage reference from our app
final storageRef = FirebaseStorage.instance.ref();

// Create a reference to "mountains.jpg"
final mountainsRef = storageRef.child("mountains.jpg");

// Create a reference to 'images/mountains.jpg'
final mountainImagesRef = storageRef.child("images/mountains.jpg");

// While the file names are the same, the references point to different files
assert(mountainsRef.name == mountainImagesRef.name);
assert(mountainsRef.fullPath != mountainImagesRef.fullPath);

אחרי שיוצרים הפניה מתאימה, קוראים למתודה putFile(), putString() או putData() כדי להעלות את הקובץ ל-Cloud Storage.

אי אפשר להעלות נתונים עם הפניה לשורש של קטגוריית Cloud Storage. ההפניה צריכה להפנות לכתובת URL של אתר צאצא.

העלאה מקובץ

כדי להעלות קובץ, קודם צריך לקבל את הנתיב המוחלט למיקום שלו במכשיר. לדוגמה, אם קובץ קיים בספריית המסמכים של האפליקציה, צריך להשתמש בחבילה הרשמית path_provider כדי ליצור נתיב קובץ ולהעביר אותו אל putFile():

Directory appDocDir = await getApplicationDocumentsDirectory();
String filePath = '${appDocDir.absolute}/file-to-upload.png';
File file = File(filePath);

try {
  await mountainsRef.putFile(file);
} on firebase_core.FirebaseException catch (e) {
  // ...
}

העלאה ממחרוזת

אפשר להעלות נתונים כמחרוזת גולמית, מקודדת בפורמט base64,‏ base64url או data_url באמצעות השיטה putString(). לדוגמה, כדי להעלות מחרוזת טקסט שמקודדת ככתובת URL של נתונים:

String dataUrl = 'data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==';

try {
  await mountainsRef.putString(dataUrl, format: PutStringFormat.dataUrl);
} on FirebaseException catch (e) {
  // ...
}

העלאת נתונים גולמיים

אפשר להעלות נתונים מוקלדים ברמה נמוכה יותר בפורמט Uint8List במקרים שבהם העלאה של מחרוזת או של File לא מעשית. במקרה הזה, קוראים לשיטה putData() עם הנתונים:

try {
  // Upload raw data.
  await mountainsRef.putData(data);
} on firebase_core.FirebaseException catch (e) {
  // ...
}

קבלת כתובת URL להורדה

אחרי העלאת קובץ, אפשר לקבל כתובת URL להורדת הקובץ על ידי קריאה לשיטה getDownloadUrl() ב-Reference:

await mountainsRef.getDownloadURL();

הוספת מטא-נתונים של קובץ

אפשר גם לכלול מטא-נתונים כשמעלים קבצים. המטא-נתונים האלה מכילים מאפיינים אופייניים של מטא-נתונים של קבצים, כמו contentType (שנקרא בדרך כלל סוג MIME). השיטה putFile() מסיקה באופן אוטומטי את סוג ה-MIME מהתוסף File, אבל אפשר לשנות את הסוג שזוהה אוטומטית על ידי ציון contentType במטא-נתונים. אם לא מציינים contentType ו-Cloud Storage לא יכול להסיק ברירת מחדל מתוך סיומת הקובץ, Cloud Storage משתמש ב-application/octet-stream. איך משתמשים במטא-נתונים של קבצים

try {
  await mountainsRef.putFile(file, SettableMetadata(
    contentType: "image/jpeg",
  ));
} on firebase_core.FirebaseException catch (e) {
  // ...
}

נהל העלאות

בנוסף להפעלת העלאות, אפשר להשהות, להמשיך ולבטל העלאות באמצעות הפונקציות pause(), resume() ו-cancel(). השהיה והפעלה מחדש של אירועים מעלות שינויים במצב pause ו-progress בהתאמה. ביטול העלאה גורם להעלאה להיכשל עם שגיאה שמציינת שההעלאה בוטלה.

final task = mountainsRef.putFile(largeFile);

// Pause the upload.
bool paused = await task.pause();
print('paused, $paused');

// Resume the upload.
bool resumed = await task.resume();
print('resumed, $resumed');

// Cancel the upload.
bool canceled = await task.cancel();
print('canceled, $canceled');

מעקב אחר התקדמות ההעלאה

אתם יכולים להאזין לזרם האירועים של משימה כדי לטפל בהצלחה, בכישלון, בהתקדמות או בהפסקות במשימת ההעלאה:

סוג האירוע שימוש רגיל
TaskState.running האירוע הזה מופעל מעת לעת במהלך העברת הנתונים, ואפשר להשתמש בו כדי לאכלס את האינדיקטור של ההעלאה או ההורדה.
TaskState.paused האירוע מופעל בכל פעם שהמשימה מושהית.
TaskState.success האירוע הזה מופעל כשהמשימה מסתיימת בהצלחה.
TaskState.canceled האירוע מופעל בכל פעם שהמשימה מבוטלת.
TaskState.error האירוע מופעל כשההעלאה נכשלה. זה יכול לקרות בגלל פסק זמן ברשת, כשלים בהרשאה או אם מבטלים את המשימה.
mountainsRef.putFile(file).snapshotEvents.listen((taskSnapshot) {
  switch (taskSnapshot.state) {
    case TaskState.running:
      // ...
      break;
    case TaskState.paused:
      // ...
      break;
    case TaskState.success:
      // ...
      break;
    case TaskState.canceled:
      // ...
      break;
    case TaskState.error:
      // ...
      break;
  }
});

טיפול בשגיאות

יכולות להיות כמה סיבות לשגיאות בהעלאה, כולל קובץ מקומי שלא קיים או משתמש שאין לו הרשאה להעלות את הקובץ הרצוי. מידע נוסף על שגיאות זמין בקטע Handle Errors במסמכי התיעוד.

דוגמה מלאה

בהמשך מוצגת דוגמה מלאה להעלאה עם מעקב אחר ההתקדמות וטיפול בשגיאות:

final appDocDir = await getApplicationDocumentsDirectory();
final filePath = "${appDocDir.absolute}/path/to/mountains.jpg";
final file = File(filePath);

// Create the file metadata
final metadata = SettableMetadata(contentType: "image/jpeg");

// Create a reference to the Firebase Storage bucket
final storageRef = FirebaseStorage.instance.ref();

// Upload file and metadata to the path 'images/mountains.jpg'
final uploadTask = storageRef
    .child("images/path/to/mountains.jpg")
    .putFile(file, metadata);

// Listen for state changes, errors, and completion of the upload.
uploadTask.snapshotEvents.listen((TaskSnapshot taskSnapshot) {
  switch (taskSnapshot.state) {
    case TaskState.running:
      final progress =
          100.0 * (taskSnapshot.bytesTransferred / taskSnapshot.totalBytes);
      print("Upload is $progress% complete.");
      break;
    case TaskState.paused:
      print("Upload is paused.");
      break;
    case TaskState.canceled:
      print("Upload was canceled");
      break;
    case TaskState.error:
      // Handle unsuccessful uploads
      break;
    case TaskState.success:
      // Handle successful uploads on complete
      // ...
      break;
  }
});

אחרי שהעליתם קבצים, נלמד איך להוריד אותם מ-Cloud Storage.