------------------------- | File Upload Screen | |-----------------------| | [Choose Image] | | | | Upload Progress: 0% | | | | [Upload Image] | | | | Uploaded Image Preview | | [No image selected] | -------------------------
Cloud Storage for files in Flutter - Mini App: Build & Ship
import 'package:flutter/material.dart'; class FileUploadScreen extends StatefulWidget { @override State<FileUploadScreen> createState() => _FileUploadScreenState(); } class _FileUploadScreenState extends State<FileUploadScreen> { // TODO: Add variables for image file, upload progress, and download URL @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('File Upload Screen')), body: Padding( padding: const EdgeInsets.all(16), child: Column( children: [ ElevatedButton( onPressed: () { // TODO: Implement image picker }, child: const Text('Choose Image'), ), const SizedBox(height: 20), // TODO: Show selected image preview or placeholder const SizedBox(height: 20), ElevatedButton( onPressed: () { // TODO: Implement upload to cloud storage }, child: const Text('Upload Image'), ), const SizedBox(height: 20), // TODO: Show upload progress const SizedBox(height: 20), // TODO: Show uploaded image from cloud URL ], ), ), ); } }
import 'dart:io'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import 'package:firebase_storage/firebase_storage.dart'; class FileUploadScreen extends StatefulWidget { @override State<FileUploadScreen> createState() => _FileUploadScreenState(); } class _FileUploadScreenState extends State<FileUploadScreen> { File? _imageFile; double _uploadProgress = 0.0; String? _downloadUrl; final ImagePicker _picker = ImagePicker(); Future<void> _pickImage() async { final XFile? pickedFile = await _picker.pickImage(source: ImageSource.gallery); if (pickedFile != null) { setState(() { _imageFile = File(pickedFile.path); _downloadUrl = null; _uploadProgress = 0.0; }); } } Future<void> _uploadImage() async { if (_imageFile == null) return; final fileName = DateTime.now().millisecondsSinceEpoch.toString(); final ref = FirebaseStorage.instance.ref().child('uploads/$fileName.jpg'); final uploadTask = ref.putFile(_imageFile!); uploadTask.snapshotEvents.listen((TaskSnapshot snapshot) { setState(() { _uploadProgress = snapshot.bytesTransferred / snapshot.totalBytes; }); }); try { await uploadTask; final url = await ref.getDownloadURL(); setState(() { _downloadUrl = url; }); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Upload failed: $e')), ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('File Upload Screen')), body: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ ElevatedButton( onPressed: _pickImage, child: const Text('Choose Image'), ), const SizedBox(height: 20), _imageFile != null ? Image.file(_imageFile!, height: 150) : const Text('No image selected'), const SizedBox(height: 20), ElevatedButton( onPressed: _uploadImage, child: const Text('Upload Image'), ), const SizedBox(height: 20), Text('Upload Progress: ${(_uploadProgress * 100).toStringAsFixed(0)}%'), const SizedBox(height: 20), _downloadUrl != null ? Image.network(_downloadUrl!, height: 150) : const SizedBox.shrink(), ], ), ), ); } }
This solution uses the image_picker package to let the user select an image from their gallery. The selected image file is stored in a File variable and shown as a preview.
When the user taps the upload button, the app uploads the image file to Firebase Cloud Storage under a unique filename based on the current timestamp.
The upload progress is tracked by listening to snapshotEvents from the upload task, and the UI updates the progress percentage accordingly.
After the upload completes, the app fetches the download URL from Firebase Storage and displays the uploaded image from the cloud.
This approach gives a clear, simple UI for picking, uploading, and viewing images stored in the cloud.
------------------------- | File Upload Screen | |-----------------------| | [Choose Image] | | | | (Image preview here) | | | | [Upload Image] | | | | Upload Progress: 75% | | | | (Uploaded image here) | -------------------------
Practice
FirebaseStorage.instance.ref() in Flutter apps?Solution
Step 1: Understand FirebaseStorage.instance.ref()
This method creates a reference to a specific location in Firebase Cloud Storage where files can be managed.Step 2: Identify its role in file handling
It is used to point to folders or files for uploading or downloading, not for app initialization or user authentication.Final Answer:
To create a reference to a location in cloud storage where files can be uploaded or downloaded. -> Option BQuick Check:
ref() creates storage location reference [OK]
- Confusing ref() with Firebase app initialization
- Thinking ref() handles user authentication
- Assuming ref() accesses local files
imageFile to Firebase Storage in Flutter?Solution
Step 1: Check the correct method for uploading files
The method to upload a file isputFile()called on a reference fromFirebaseStorage.instance.ref().Step 2: Match the syntax
await FirebaseStorage.instance.ref('images/image.png').putFile(imageFile); correctly usesawait FirebaseStorage.instance.ref('path').putFile(file). Other options use incorrect method names or call patterns.Final Answer:
await FirebaseStorage.instance.ref('images/image.png').putFile(imageFile); -> Option AQuick Check:
Use ref().putFile() to upload [OK]
- Using incorrect method names like uploadFile or upload
- Calling putFile directly on FirebaseStorage without ref()
- Omitting await for asynchronous upload
final ref = FirebaseStorage.instance.ref('docs/report.pdf');
final url = await ref.getDownloadURL();
print(url);
What will be printed by this code?Solution
Step 1: Understand getDownloadURL()
This method returns a URL string that points to the file stored in Firebase Storage at the given reference.Step 2: Analyze the code output
The code prints the URL string, not local paths, errors, or file content.Final Answer:
A string URL that can be used to download the file 'report.pdf' from Firebase Storage. -> Option DQuick Check:
getDownloadURL() returns file URL [OK]
- Thinking it returns local file path
- Expecting file content instead of URL
- Assuming error if file not uploaded (only if missing)
final ref = FirebaseStorage.instance.ref('uploads/photo.jpg');
ref.putFile(photoFile);
What is the likely cause of the error?Solution
Step 1: Check asynchronous call usage
The methodputFile()returns a Future and should be awaited or handled properly.Step 2: Identify missing await
Not usingawaitor.then()can cause errors or unhandled Futures in Flutter async code.Final Answer:
Missing await keyword before putFile causing unhandled Future. -> Option CQuick Check:
Always await async upload calls [OK]
- Forgetting await on putFile()
- Confusing ref() usage
- Passing wrong file type without checking
List<File> images to Firebase Storage under folder 'gallery/'. Which approach correctly uploads all files and collects their download URLs?Solution
Step 1: Upload files sequentially with await
Uploading each file with await ensures each upload completes before moving on, preventing errors.Step 2: Get download URLs after each upload
After each upload, callgetDownloadURL()on the file's reference to get its URL and store it.Step 3: Collect URLs in a list
Store each URL in a list to use later, ensuring all files are uploaded and URLs are valid.Final Answer:
Use a loop with await inside to upload each file and then call getDownloadURL() for each upload, storing URLs in a list. -> Option AQuick Check:
Upload with await, then getDownloadURL() per file [OK]
- Not awaiting uploads causing race conditions
- Calling getDownloadURL() before upload
- Assuming one getDownloadURL() call returns all URLs
Ready to prove it?
Pass the test and this pattern moves unknown
