#100DaysOfCodeChallenge - Crop Management Information System - Day 9
Tags: 100daysofcode, flutter, dart
Published: 2021-07-04 01:09:18

## Recap

On [Day 8](https://dev.to/curtlycritchlow/100daysofcodechallenge-crop-management-information-system-day-8-540p) we solved the `PlatformException (PlatformException(no_available_camera, No cameras available for taking pictures., null, null))` 


## Overview

In this post we will discuss how to access the device camera and save photo in cloud storage. 


## Going Deeper

We will use the device camera to take a photo, next, we will save the photo to cloud storage and finally we will save the url reference of the cloud storage photo to the farmer document on cloud firestore.

### Using Device Camera.
```Dart

class _AddFarmerScreenController extends State<AddFarmerScreen> {
  @override
  Widget build(BuildContext context) => _AddFarmerScreenView(this);
  FarmerServiceModel farmer = FarmerServiceModel.form();

  final _picker = ImagePicker();
  PickedFile? _pickedFile;
  late File? _farmerProfilePicture;
}
```

To recap, the class `_AddFarmerScreenController()` is responsible for the all the logic associated with the class `_AddFarmerScreenView()`. The latter class is responsible for the layout of the `AddFarmerScreen`.

The `ImagePicker()`  is from the flutter [image_picker](https://pub.dev/packages/image_picker) package. This class gives us access to the methods we'll need to use the device camera.

`PickedFile` is returned from the method call that takes a photo from the device camera.

`File` is the photo that will be stored in cloud storage.

### Take Photo Method

```Dart

  void _handleTakePhoto() async {
    _pickedFile = await _picker.getImage(source: ImageSource.camera);
    _farmerProfilePicture = File(_pickedFile!.path);
    setState(() {});
  }
```

`_handleTakePhoto()` will be called when the user press the take farmer picture button. `_picker.getImage(source: ImageSource.camera)` is the method that gives us access to the device camera. The returned photo is a `PickedFile`. The `_pickedFile` is converted to a `File` by `File(_pickedFile!.path)` and stored in the `_farmerProfilePicture` variable.

```Dart

  ImageProvider<Object>? _imagePreview() {
    if (_pickedFile != null) {
      if (kIsWeb) {
        return NetworkImage(_pickedFile!.path);
      } else {
        return FileImage(File(_pickedFile!.path));
      }
    } else {
      return null;
    }
  }
```

`_imagePreview()` method is assigned to: 
```Dart

CircleAvatar(
  backgroundImage: state._imagePreview(),
  minRadius: 200.0,
),
```

This widget displays a preview of the photo taken as shown in the screenshot below.
![Preview of Farmer Profile](https://drive.google.com/uc?id=1m0eM0vGYTpXR73SXrJbX37NoCC0FyctK)

### Saving Form Data
```Dart
  void _handleRegisterFarmer() async {
    if (_formkey.currentState!.validate()) {
      _formkey.currentState!.save();
      farmer.saveRegistrationNumber('');
      AddFarmerCommand(context).run(
          farmerServiceModel: farmer,
          context: context,
          farmerProfilePicture: _farmerProfilePicture);
    }
  }
```

When the form data is saved, the farmer's profile picture is passed to the `AddFarmerCommand().run()` method along with the other farmer data and the build context.

### Saving farmer profile picture to cloud storage.

```Dart
/// This class is responsible for farmer registration.
class AddFarmerCommand extends BaseCommand {
  AddFarmerCommand(BuildContext c) : super(c);

  /// Calls FarmerService.addFarmer method
  ///
  /// Receives farmer data and buildcontext from widget and pass it to the farmerService.addFarmer and fileService.uploadFarmerProfilePicture method.
  Future<bool> run({
    required FarmerServiceModel farmerServiceModel,
    required File? farmerProfilePicture,
    required BuildContext context,
  }) async {
    bool farmerAddedSuccess = false;

    if (farmerProfilePicture != null) {
      final farmerProfilePictureUrl =
          await fileservice.uploadFarmerProfilePicture(farmerProfilePicture);
      farmerServiceModel.saveProfilePicture(farmerProfilePictureUrl);
    }
    await farmerService
        .addFarmer(farmerServiceModel: farmerServiceModel)
        .then((value) => farmerAddedSuccess = true);
    return farmerAddedSuccess;
  }
}
```

This method is comprised of two main parts. `await fileservice.uploadFarmerProfilePicture()` and `await farmerService.addFarmer()`

#### fileService.uploadFarmerProfilePicture()

Only if the farmer's profile picture is not null, the `fileService.uploadFarmerProfilePicture()` method will be called. 
```Dart
class FileStorageService {
  final storage = firebase_storage.FirebaseStorage.instance;

  Future<String?> uploadFarmerProfilePicture(
    File farmerProfilePicture,
  ) async {
    String? farmerProfilePictureUrl;
    try {
      await storage
          .ref()
          .child('farmer_profile_picture')
          .child(basename(farmerProfilePicture.path))
          .putFile(farmerProfilePicture)
          .then((value) async {
        farmerProfilePictureUrl = await value.ref.getDownloadURL();
      });
    } on firebase_storage.FirebaseException catch (e) {
      // e.g, e.code == 'canceled'
      print(e);
    }
    return farmerProfilePictureUrl;
  }
}
```
The `farmerProfilePicture` is saved in cloud storage using `await storage.ref().child().child.putFile().then()` method. It saves the `farmerProfilePicture` in a `farmer_profile_picture` folder. It then returns a url reference to the file in the `then()` method. This reference is stored in cloud firestore along with the remainder of the farmer data when the `await farmerService.addFarmer()` method is called.

## Wrap Up

In this post, we discussed how to save a photo from the device camera in cloud storage and store a url cloud reference of the photo from cloud storage with the remainder of the farmer data in cloud firestore.

Below are screenshots of the process.

![Preview of Farm Data](https://drive.google.com/uc?id=1W6hXDJdY0Z5nvi6URbhRCbSM_3dK2gNu)

![Preview of Farmer Profile picture in cloud storage](https://drive.google.com/uc?id=1pjaUVLxlJfQdvMgoKJxtIiIx0F5PtEnB)

![Preview of Farmer Profile picture in cloud storage](https://drive.google.com/uc?id=1vhfucjdUMH3_pJmeivn240AtOGS2FEm-)


## Connect with me

Thank you for reading my post. Feel free to subscribe below to join me on the #100DaysOfCodeChallenge or connect with me on [LinkedIn](https://www.linkedin.com/in/curtlycritchlow/) and [Twitter](https://twitter.com/CritchlowCurtly). You can also [buy me a book](https://www.buymeacoffee.com/curtlycritchlow) to show your support.