Upload Profile Photo to Cloud Storage Flutter
This is a detailed and easy-to-sympathise guide to working with Flutter and Firebase Storage. We will build an app with mutual functionality like uploading images, displaying uploaded images from Firebase Storage in a ListView, and deleting some of the uploaded images from right inside the application.
Flutter and Firebase-related packages are updated and then frequently thus I recently updated this article to fix naught safety related errors and compatibility issues. Advertisements
Overview
Prerequisites
To follow along and become the most out of this tutorial, you lot need the following: Advertisements
- Basic cognition well-nigh Flutter.
- A registered Firebase account with a fix-to-use project.
- Flutter version 2.v or newer with Firebase SDK correctly installed. If not, delight check this article kickoff: Flutter: Configure Firebase for iOS and Android.
Note that if you use an one-time version of Flutter (1.ten), in that location may be (a lot of) errors and incompatibilities.
Packages used in the example
Likewise firebase_core (which you take to install when adding Firebase SDK), we'll need the following packages:
- firebase_storage: Provides Firebase Cloud Storage API
- image_picker: Used for picking images from the image library or taking photos with the photographic camera.
- path: A path manipulation library.
The Complete Case
Preview
App demo:
Uploaded images on Firebase Storage:
Note: The iOS simulator doesn't let using the camera. If y'all want this, play with your Android emulator or a real device.
Installing required plugins
Advertisements
Add firebase_storage, image_picker, path_provider, path, and their versions to the dependencies department in your pubspec.yaml file:
dependencies: flutter: sdk: palpitate firebase_core: ^1.12.0 path: ^1.eight.1 firebase_storage: ^ten.2.7 image_picker: ^0.8.four+9 With the image_picker plugin, we accept to do some extra setups for iOS and Android.
iOS
Go to <your-project>/ios/Runner/Info.plist and add the following betwixt <dict> and </dict>:
<primal>NSCameraUsageDescription</key> <string>Some Clarification</string> <cardinal>NSMicrophoneUsageDescription</key> <string>Some Description</string> <key>NSPhotoLibraryUsageDescription</primal> <string>Some Clarification</string> If you are not familiar with this stuff, have a look at my screenshot:
Actually, we don't demand the microphone permission but adding it won't crusade whatever harm.
Android
- API< 29: No activity required.
- API 29+: Add android:requestLegacyExternalStorage="truthful" as an attribute to the tag in your AndroidManifest.xml. The attribute is false by default on apps targeting Android Q.
Getting Firebase Storage Ready
Go to your project dashboard on Firebase Panel, select "Storage" from the left-paw menu and then you can encounter the bucket path equally shown in the screenshot beneath:
You don't have to manually add the path to your Flutter code because it will be handled automatically by Firebase packages.
For simplicity's sake, we volition Not implement hallmark in this example. Therefore, we need to change the rules for Firebase Storage to be public, like this:
Advertisements
Now everything is ready and the job is writing code.
The total code
The code with explantations:
// primary.dart import 'packet:flutter/foundation.dart'; import 'parcel:flutter/material.sprint'; import 'sprint:io'; import 'package:firebase_core/firebase_core.dart'; import 'packet:firebase_storage/firebase_storage.dart'; import 'package:path/path.dart' as path; import 'package:image_picker/image_picker.sprint'; void master() async { WidgetsFlutterBinding.ensureInitialized(); // Initialize a new Firebase App instance await Firebase.initializeApp(); runApp(const MyApp()); } course MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { render MaterialApp( // Remove the debug imprint debugShowCheckedModeBanner: imitation, championship: 'Kindacode.com', theme: ThemeData(primarySwatch: Colors.green), home: const HomePage(), ); } } class HomePage extends StatefulWidget { const HomePage({Key? central}) : super(key: fundamental); @override _HomePageState createState() => _HomePageState(); } grade _HomePageState extends State<HomePage> { FirebaseStorage storage = FirebaseStorage.instance; // Select and paradigm from the gallery or take a picture with the camera // Then upload to Firebase Storage Future<void> _upload(String inputSource) async { concluding picker = ImagePicker(); XFile? pickedImage; endeavor { pickedImage = await picker.pickImage( source: inputSource == 'camera' ? ImageSource.photographic camera : ImageSource.gallery, maxWidth: 1920); concluding String fileName = path.basename(pickedImage!.path); File imageFile = File(pickedImage.path); try { // Uploading the selected epitome with some custom meta information await storage.ref(fileName).putFile( imageFile, SettableMetadata(customMetadata: { 'uploaded_by': 'A bad guy', 'description': 'Some description...' })); // Refresh the UI setState(() {}); } on FirebaseException grab (error) { if (kDebugMode) { impress(error); } } } catch (err) { if (kDebugMode) { print(err); } } } // Retriew the uploaded images // This function is chosen when the app launches for the first time or when an paradigm is uploaded or deleted Hereafter<Listing<Map<Cord, dynamic>>> _loadImages() async { Listing<Map<Cord, dynamic>> files = []; final ListResult event = await storage.ref().listing(); last List<Reference> allFiles = result.items; await Futurity.forEach<Reference>(allFiles, (file) async { final String fileUrl = expect file.getDownloadURL(); final FullMetadata fileMeta = await file.getMetadata(); files.add together({ "url": fileUrl, "path": file.fullPath, "uploaded_by": fileMeta.customMetadata?['uploaded_by'] ?? 'Nobody', "description": fileMeta.customMetadata?['description'] ?? 'No description' }); }); return files; } // Delete the selected epitome // This function is chosen when a trash icon is pressed Futurity<void> _delete(String ref) async { await storage.ref(ref).delete(); // Rebuild the UI setState(() {}); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Kindacode.com'), ), trunk: Padding( padding: const EdgeInsets.all(twenty), kid: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ ElevatedButton.icon( onPressed: () => _upload('photographic camera'), icon: const Icon(Icons.camera), characterization: const Text('camera')), ElevatedButton.icon( onPressed: () => _upload('gallery'), icon: const Icon(Icons.library_add), characterization: const Text('Gallery')), ], ), Expanded( child: FutureBuilder( future: _loadImages(), builder: (context, AsyncSnapshot<List<Map<String, dynamic>>> snapshot) { if (snapshot.connectionState == ConnectionState.done) { return ListView.architect( itemCount: snapshot.data?.length ?? 0, itemBuilder: (context, index) { final Map<String, dynamic> image = snapshot.data![index]; return Carte du jour( margin: const EdgeInsets.symmetric(vertical: 10), kid: ListTile( dumbo: false, leading: Image.network(image['url']), title: Text(image['uploaded_by']), subtitle: Text(image['description']), trailing: IconButton( onPressed: () => _delete(paradigm['path']), icon: const Icon( Icons.delete, color: Colors.red, ), ), ), ); }, ); } return const Center( child: CircularProgressIndicator(), ); }, ), ), ], ), ), ); } } Note: The app is intended to be every bit simple as possible then the code is shorter and cleaner. It has but one screen and uses a stateful widget for state direction. It too lacks many production features such as epitome preview before upload, authentication, authorization, and UI/UX optimization. You can better these things on your ain to go a better result.
Decision
Together we've built a Flutter application that works with Firebase Storage in uploading, retrieving, and deleting files. A lot of code was written and information technology's totally fine if you don't absorb them all in one hour or ii. The nigh important matter is that we've got the job done, nosotros've fabricated something consummate, at least on a very small piece of Palpitate and Firebase. Doing a lot of exercise volition assist you lot master that noesis and speedily deploy them in your future projects.
Advertisements If you'd like to explore more crawly stuff about Flutter, take a look at the following articles:
- Flutter and Firestore Database: CRUD example
- Working with Time Picker in Flutter
- Flutter StreamBuilder examples
- Write a simple BMI Calculator with Flutter
- Flutter: Check Internet Connexion without any plugins
- Palpitate Cupertino ActionSheet: Tutorial & Case
- Flutter: Caching Network Images for Big Functioning gains
You lot can too check out our Flutter topic page or Dart topic page for the latest tutorials and examples.
Source: https://www.kindacode.com/article/flutter-firebase-storage/
0 Response to "Upload Profile Photo to Cloud Storage Flutter"
Post a Comment