Upload and Retrieve Images on MongoDB using Dart in Flutter

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

filter_none

edit
close

play_arrow

link
brightness_4
code

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"
];

chevron_right


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

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


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

filter_none

edit
close

play_arrow

link
brightness_4
code

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
      );
     }
}

chevron_right


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

filter_none

edit
close

play_arrow

link
brightness_4
code

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
});

chevron_right


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

filter_none

edit
close

play_arrow

link
brightness_4
code

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");
  }
}

chevron_right


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




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.