Using Flutter, Firebase, and NodeJs for your startup app

Atanu Dasgupta
5 min readDec 6, 2019

--

Continuous learning

In a startup environment, it becomes important to choose the right technologies to build your MVP. I tend to choose technologies on the following parameters. Flutter and Firebase have caught up very well with Startup community as a sensible tool for building new products.

  1. Recurring cost of using the technology choices
  2. Ease of use.
  3. Whether it supports NFRs such as scalability, security, reliability, etc..
  4. Shorter learning curve for a newcomer.
  5. Faster time to delivery
  6. Ease of maintenance and adding features.
  7. Support for modern software needs such as Cloud, REST, ML , CI/CD etc..

In my search for technology choices, I found Flutter, Firebase, and Cloud functions using NodeJs extremely helpful. Firebase provides the backend services using cloud functions, Firestore database, Cloud storage, ML language translation, etc.. at no additional cost in the spark plan. In my case, I had to use external services such as mailgun for sending emails, so I had to upgrade to Blaze plan, however, unless my usage crosses a threshold there is no charge on the credit card. I had used pdfkit to generate pdfs and then using mailgun I was able to send it as an attachment.

I also think for a startup unless you have investors, it best to keep the development team small and if possible do it yourself ! There is enough learning materials on the internet.

In this article, I show you some of the code snippets to demonstrate the power of these technologies using which I could develop a good quality app in just 3 months.

Firebase and Flutter examples:

a) One of the important usage of Firebase for authentication which comes along with Firebase and works well with Flutter. Flutter uses dart programming language which constructs a widget tree and gives enormous flexibility to wrap widgets with another and also create stateful and stateless widgets.

  1. Google Sign-in is required nowadays for all new applications which are in B2C space. The example shows how easy it is to implement authentication for googleSignIn for your flutter app.
Future<FirebaseUser> googleSignIn() async {
// Start
loading.add(true);
FirebaseUser user;

try {
// Step 1
GoogleSignInAccount googleUser = await _googleSignIn.signIn();

// Step 2
GoogleSignInAuthentication googleAuth =
await googleUser.authentication.catchError((err) {
print('Cannot get token');
});
user = await _auth.signInWithGoogle(
accessToken: googleAuth.accessToken, idToken: googleAuth.idToken);

// Step 3
updateUserData(user);

// Done
loading.add(false);

print('signed in ' + user.displayName);
} catch (e) {
print('error connecting to Firebase google signin');
user = null;
}
return user;
}

You can now use the above method in your main.dart to authenticate the user and then navigate to the next screen easily. In Firebase Firestore which is a document database you can store the user information such as name, email etc.. post the authentication.

Here is a usage of the above in main.dart

Padding(
padding: EdgeInsets.only(top: 10.0),
child: GestureDetector(
onTap: () async {
FirebaseUser fUser;
await authService.googleSignIn().then((u) {
fUser = u;
});

showInSnackBar('Welcome ' + fUser.displayName);
bool _check;
// check if the user profile is updated
try {
_check = await authService.getUserData(fUser.email);
} catch (e) {
print(e.message);
print("Failed in getUserData");
}

Navigator.push(
context,
new MaterialPageRoute(
builder: (ctxt) {
if (_check)
return VideoPlayerApp(email: fUser.email);

2. Another powerful in Flutter is called the StreamBuilder. Imagine you now want to provide the functionality to the user where he can view and update his profile. In this use-case first, you need to fetch the save profile information to flutter and then provide an ability to modify them and save it back to FireStore. Look at this code snippet below.

@override
Widget build(BuildContext context) {

return StreamBuilder<DocumentSnapshot>(
stream: Firestore.instance.collection(DB).document(email).snapshots(),
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError) return new Text('Error: ${snapshot.error}');

return Container(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(height: 20),
TextFormField(
initialValue: snapshot.data['displayName'],

onSaved: (text) {
values.insert(0, text);

},
validator: (value) {
if (value.isEmpty)
return ('Enter valid name');
else
return null
;
},

In the above code, the collection in FireStore called DB has a document for each user with unique email addresses. This document contains the user profile information saved earlier. Now, we need to retrieve it using a snapshot display in TextField Widget appropriately. TextField widget has onSaved event which gets triggered when the Form is saved and then we capture the new value if any. Validators are used to validate user inputs.

Cloud Functions using Typescript

This is another area where using Firebase helps a lot. We can easily write and deploy cloud functions on NodeJs running on Firebase Cloud.

Here the documentation in Firebase I would say is a bit weak, I would have preferred more concrete documentation on usage from Firebase for cloud functions. However, once you are able to learn it, it works very well.

There are setups to be done using Firebase console including API keys, service accounts etc.. , which can be a bit challenging initially. You can find lots of articles on Medium to do this.

  1. Once the setups are done correctly and you have NodeJs on your laptop and a visual editor you are all set to write the first function in index.ts.

First, you must import the firebase packages to use such as

import * as functions from ‘firebase-functions’;

import * as admin from ‘firebase-admin’;

If you are dealing with images or large files its useful to use axios which helps in creating Buffers from the file content.

I am using the ServiceAccounts, which means you need to download the JSON file with keys etc..

const serviceAccount = require(“./serviceAccountKey.json”);

admin.initializeApp({

credential: admin.credential.cert(serviceAccount),

})

If you want to use the Cloud storage ( which is free) to store files then you can access the buckets using Firebase.admin.

const storage = admin.storage()

const file = storage.bucket().file(filename)

In the above statement, I am creating a new file in the default bucket with a variable passed in the filename.

2. Another interesting area of Firebase function is the triggers. We have database trigger and storage triggers which are very helpful. They trigger based on the kind of event you want to listen to.

Example :

export const generatePDF= functions.firestore.document(‘payments/{any}’).onUpdate(async (change, context) => {

The above definition of function listens to any change in payment document in FireStore and triggers this function which would help in generating a pdf using PDFkit and then email to the user using mailgun.

Note: This all happens automatically from Firebase backend service without having to worry about it. Firebase has stackdriver logging and a dashboard to track if things are going fine.

That's all for today, I plan to cover each of these topics in more detail in a later article. If you like the article please clap!

Here are some links that I found useful while learning myself.

  1. Flutter Samples
  2. Flutter packages
  3. Firebase for Flutter
  4. App Brewery
  5. Fireship

--

--

Atanu Dasgupta
Atanu Dasgupta

Written by Atanu Dasgupta

technology enthusiast with passion for learning

No responses yet