Open In App

Upload and Retrieve Images on MongoDB using Dart in Flutter

Improve
Improve
Like Article
Like
Save
Share
Report

To upload files from a local system to the dedicated server is called file uploading and retrieval files from the dedicated server to a local system is called file retrieving.  It works exactly the same as the definition when we select a file from the Android device and click the submit button, the Android device takes the file from the local storage and sends it to the server with the help of an Http request and the server does its job to save the file to the defined location. In this article, we are demonstrating how image files are stored and retrieved into the MongoDB Atlas cluster database along with compressing the size of images form Megabytes(MBs) to Kilobytes(KB) with the help of the flutter_image_compress plugin.

Prerequisite: For getting started with this an individual needs to be familiar with the following

  • Flutter
  • Dart
  • MongoDB
  • Mongo Dart

Here, We are creating an Android application to demonstrate the use of MongoDB in the Flutter application. To get started we need to install certain Flutter packages & plugins and Android Studio must be installed in the local system.

Before getting started Flutter development toolkit in the local system and  Flutter plugin in Android Studio IDE must be installed.

  • Open Android Studio and create a new flutter application project with a name called ‘geeksforgeeks’.
  • Once the project is created and sync successfully, connect your Android device to Android Studio, and make sure Developer options and USB debugging are On.
  • Run the project by clicking on the first green icon at the center top to cross-check the project is built and running successfully(first time Android Studio takes a little more time as usual).
  • Now, It’s time to install the necessary packages & plugins, open the ‘pubspec.yaml’ file from geeksforgeeks -> pubspec.yaml project structure and copy-paste three dependencies that are image_picker, flutter_image_compress, and mongo_dart as follows.
dependencies:
  image_picker: ^0.6.7+7
  flutter_image_compress: ^0.7.0
  mongo_dart:
    git:
      url: https://github.com/mongo-dart/mongo_dart.git
  • Once, you have done the above steps then click on ‘Packages get’ flutter command appearing at the center top to get install all necessary packages and plugins.

To upload and retrieve an image on MongoDB using Dart in flutter lets begin, follow each and every step below one by one.

Step 1:

Since this entire application is built on the top of the Android smartphone hence it won’t be possible to connect with the local MongoDB database that’s why here, we will be using the MongoDB cluster database, and to connect with cluster database all we need replicas’ URIs.

  • Signup or Login to MongoDB account and create a database with any custom name.
  • To get these replicas from Atlas, got to ‘Connect’ -> ‘Connect with Shell’ -> ‘I have the Mongo Shell installed’ -> set your version to 3.4 or earlier.
  • If you have 3 replicas, you will have 3 URLs split up with commas like below.

Dart




final url = [
      "mongodb://<username>:<password>@<hostname1>:27017/<DBName>?ssl=true&
      replicaSet=<MySet>&authSource=admin&retryWrites=true&w=majority",
      "mongodb://<username>:<password>@<hostname2>:27017/<DBName>?ssl=true&
      replicaSet=<MySet>&authSource=admin&retryWrites=true&w=majority",
      "mongodb://<username>:<password>@<hostname3>:27017/<DBName>?ssl=true&
      replicaSet=<MySet>&authSource=admin&retryWrites=true&w=majority"
];


Step 2: 

To begins with the database connection, Since Atlas now only allows SSL connections, we will need the source from TLS/SSL to open a secure connection. To the Db.pool() instruction we will have to pass in each of these URLs prefaced with mongodb://, followed by /test?authSource=[auth db (probably ‘admin’)] we can see an example of replicas’ URIs in the above step.

Dart




Future connection () async{
    Db _db = new Db.pool(url);
    await _db.open(secure: true);
    GridFS bucket = GridFS(_db,"image");
}


Step 3: 

Once we have established a connection to the MongoDB cluster database, we can now begin defining our back-end logic. Since uploading and retrieving long size image is very time-consuming and sometimes it leads with a bunch of problems like for example acquire more space, more costly, access time more, and more data overload therefore In this, the step we are compressing the size of an image from MB’s to KB’s with maintaining aspect ratio.

Dart




final pickedFile = await picker.getImage(source: ImageSource.gallery);
if(pickedFile!=null){
    var _cmpressed_image;
    try {
      _cmpressed_image = await FlutterImageCompress.compressWithFile(
          pickedFile.path,
          format: CompressFormat.heic,
          quality: 70
      );
     } catch (e) {
      _cmpressed_image = await FlutterImageCompress.compressWithFile(
          pickedFile.path,
          format: CompressFormat.jpeg,
          quality: 70
      );
     }
}


Step 4: 

Now, this is the fourth and final step here, we will be building queries to upload and retrieve images to MongoDB, therefore, cluster database. Since MongoDB supports JSON like(i.e key-value pair) data format therefore we will have to create a Hashmap with two key-value pairs that are ‘_id’ and ‘data’ to store image unique id and image pixel data respectively.

Dart




Map<String,dynamic> image = {
      "_id" : pickedFile.path.split("/").last,
      "data": base64Encode(_cmpressed_image)
};
  
var res = await bucket.chunks.insert(image);
var img = await bucket.chunks.findOne({
      "_id": pickedFile.path.split("/").last
});


Now, It is time to show the full approach, open ‘main.dart’ file from geeksforgeeks -> lib -> main.dart project directory structure and copy-paste following the entire code.

Dart




import 'dart:convert';
import 'dart:io';
  
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:mongo_dart/mongo_dart.dart' show Db, GridFS;
  
void main() => runApp(MyApp());
  
class MyApp extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Geeks Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: MyHomePage(title: 'GeeksforGeeks'),
    );
  }
}
  
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  
  
  final String title;
  
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
  
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{
  
  final url = [
      "mongodb://<username>:<password>@<hostname1>:27017/<DBName>?ssl=true&
      replicaSet=<MySet>&authSource=admin&retryWrites=true&w=majority",
      "mongodb://<username>:<password>@<hostname2>:27017/<DBName>?ssl=true&
      replicaSet=<MySet>&authSource=admin&retryWrites=true&w=majority",
      "mongodb://<username>:<password>@<hostname3>:27017/<DBName>?ssl=true&
      replicaSet=<MySet>&authSource=admin&retryWrites=true&w=majority"
  ];
  
  final picker = ImagePicker();
  File _image;
  GridFS bucket;
  AnimationController _animationController;
  Animation<Color> _colorTween;
  ImageProvider provider;
  var flag = false;
    
  @override
  void initState() {
  
    _animationController = AnimationController(
      duration: Duration(milliseconds: 1800),
      vsync: this,
    );
    _colorTween = _animationController.drive(ColorTween(begin: Colors.green, end: Colors.deepOrange));
    _animationController.repeat();
    super.initState();
    connection();
  }
  
  Future getImage() async{
    
    final pickedFile = await picker.getImage(source: ImageSource.gallery);
  
    if(pickedFile!=null){
  
      var _cmpressed_image;
      try {
        _cmpressed_image = await FlutterImageCompress.compressWithFile(
            pickedFile.path,
            format: CompressFormat.heic,
            quality: 70
        );
      } catch (e) {
  
        _cmpressed_image = await FlutterImageCompress.compressWithFile(
            pickedFile.path,
            format: CompressFormat.jpeg,
            quality: 70
        );
      }
      setState(() {
        flag = true;
      });
  
      Map<String,dynamic> image = {
        "_id" : pickedFile.path.split("/").last,
        "data": base64Encode(_cmpressed_image)
      };
      var res = await bucket.chunks.insert(image);
      var img = await bucket.chunks.findOne({
        "_id": pickedFile.path.split("/").last
      });
      setState(() {
        provider = MemoryImage(base64Decode(img["data"]));
        flag = false;
      });
    }
  }
    
  @override
  Widget build(BuildContext context) {
  
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        backgroundColor: Colors.green,
      ),
      body: SingleChildScrollView(
        child: Center(
          child:  Column(
            children: [
              SizedBox(
                height: 20,
              ),
              provider == null ? Text('No image selected.') : Image(image: provider,),
              SizedBox(height: 10,),
              if(flag==true)
                CircularProgressIndicator(valueColor: _colorTween),
              SizedBox(height: 20,),
              RaisedButton(
                onPressed: getImage,
                textColor: Colors.white,
                padding: const EdgeInsets.all(0.0),
                child: Container(
                  decoration: BoxDecoration(
                    gradient: LinearGradient(
                      colors: <Color>[
                        Colors.green,
                        Colors.green[200],
                        Colors.green[900],
                      ],
                    ),
                  ),
                  padding: const EdgeInsets.all(10.0),
                  child: const Text(
                      'Select Image',
                      style: TextStyle(fontSize: 20)
                  ),
                ),
  
              ),
            ],
          ),
        )
      )
  
    );
  }
  
  Future connection () async{
    Db _db = new Db.pool(url);
    await _db.open(secure: true);
    bucket = GridFS(_db,"image");
  }
}


Finally, Run the project by clicking on the first green icon at the center top to see the output, and your job gets done.

Output:

accessing image



Last Updated : 16 Oct, 2020
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads