Flutter libraries I cannot live without

Cover image

It has been some times since I started building my own messenging and reminder app. The goal of this app is to be able to message your friends and also send a reminder to your family, imagine it like a sticky note. It will remind them with the message at the right time. Sometimes it’s useful if the message is sent right away but other times it has more values if it is sent later in the day. I have used many different libraries to create the MVP and the following are ones I cannot live without.

Firebase

When I decided to use Firebase as my backend for quick prototyping and its real-time update, I started searching if there were supports in Flutter for Firebase. Fortunately it does and it has official support from Firebase team! You can read more about how to add Firebase to your Flutter project here Add Firebase to your Flutter app. If you need to have a database for your app you can use Cloud Firestore for real-time updates and easiness with query.

import ‘package:cloud_firestore/cloud_firestore.dart';

class BookList extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection(‘books’).snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError)
          return new Text(‘Error: ${snapshot.error});
        switch (snapshot.connectionState) {
          case ConnectionState.waiting: return new Text(‘Loading…’);
          default:
            return new ListView(
              children: snapshot.data.documents.map((DocumentSnapshot document) {
                return new ListTile(
                  title: new Text(document[‘title’]),
                  subtitle: new Text(document[‘author’]),
                );
              }).toList(),
            );
        }
      },
    );
  }
}

When getting the data, you can use it with StreamBuilder so you can keep your component stateless without the need to manage the state. However, keep in mind that everything inside the callback will be re-rendered so only encapsulate the component that will definitely need to re-render without rebuilding the whole component tree. There is a plugin for push notification from Firebase and if you need a way to track crashes in your app, Firebase Crashlytics is your friend as well.

Provider

There are many solutions to state management in Flutter. There are Redux, Mobx, RxDart, Bloc, or nothing at all. The solution I have adopted is Provider, This is also the current recommendation from the official Flutter team. The basic idea is you can get your state from child components using context object given that it is exposed in one of the parent components. It is very similar to the Context API in React. In Provider, you can have multiple providers as a widget that encapsulates your own widget so these child components will have access to the states that are exposed by these providers.

MultiProvider(
  providers: [
    Provider<Something>(create: (_) => Something()),
    Provider<SomethingElse>(create: (_) => SomethingElse()),
    Provider<AnotherThing>(create: (_) => AnotherThing()),
  ],
  child: someWidget,
)

In your child widget, you use a consumer to retrieve those states:

Widget build(BuildContext context) {
  return Consumer<Something>(
    builder: (BuildContext context, Something state, _) {
      return Text(state.title);
    },
  );
}

Image Picker

I thought I would need to study iOS and Android API and write my own implementation for getting images but thanks to the strong community we have around Flutter, there is a library for that. image_picker is a library exactly for this purpose. It is very straightforward to use: you choose you want to take a picture from camera or from album, it then show you the respective app based on your selection, choose or take a picture, then it will return an image file you can display or upload to your server.

import ‘package:image_picker/image_picker.dart';

class MyHomePage extends StatefulWidget {
  
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  File _image;

  Future getImage() async {
    var image = await ImagePicker.pickImage(source: ImageSource.camera);

    setState(() {
      _image = image;
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(‘Image Picker Example’),
      ),
      body: Center(
        child: _image == null
            ? Text(‘No image selected.)
            : Image.file(_image),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: getImage,
        tooltip: ‘Pick Image’,
        child: Icon(Icons.add_a_photo),
      ),
    );
  }
}

Flutter Local Notifications

Most apps nowadays will send a notification of sorts to get users come back to their apps. I don’t actually know an app that doesn’t have notification to be honest. Each platform has their own API and different guideline for their own best practices. flutter_local_notifications lets you handle in a few lines of code. Whether you want to have sound, what icon to show, schedule your notification, or platform specific action like permission requests on iOS. All of these can be customized by you.

FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
// initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project
var initializationSettingsAndroid = AndroidInitializationSettings(‘app_icon’);
var initializationSettingsIOS = IOSInitializationSettings(
    onDidReceiveLocalNotification: onDidReceiveLocalNotification);
var initializationSettings = InitializationSettings(
    initializationSettingsAndroid, initializationSettingsIOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
    onSelectNotification: onSelectNotification);

Cover photo credit goes to unsplash-logoErol Ahmed