Implementing live whiteboard with Flutter and Firestore database

Free product design tips

Join our newsletter and get insights that will change your product design perspective

or follow us

social-media-iconsocial-media-iconsocial-media-icon

Whiteboard is an irreplaceable tool in many business processes. To allow for the same kind of collaborative process using whiteboard online, live whiteboards have been created. In this blog post, we will explore a possible implementation of such a whiteboard using Flutter to create a mobile application and Firestore database as backend.

Flutter is a framework for creating cross-platform applications for mobile devices (Android and iOS), desktop (Mac and PC), and web.

Firestore is a document database offered by Google as a part of the Firebase platform. Features that make it especially well suited for use cases such as live whiteboard are low latency synchronization and the ability for clients to subscribe to notifications about data changes.

In this blog post, we will analyze the most important aspects of creating a simple whiteboard app. The app consists of two pages, the first StartPage for providing id of the whiteboard the user intends to connect to. Second WhiteboardPage displays the selected whiteboard and allows for adding and removing lines.

Live whiteboard

Rendering

Widget responsible for rendering the lines to the screen is WhiteboardView. WhiteboardView consists of a CustomPaint widget with WhiteboardPainter. WhiteboardPainter in paint method iterates over all lines and draws lines joining consecutive points to the canvas.


Rendering

WhiteboardView is also responsible for detecting user inputs and exposing appropriate onGestureStart, onGestureUpdate, and onGestureEnd callbacks. Gestures are detected using a GestureDetector widget and mapped to Point models after being scaled relative to whiteboard width. Using coordinated relative to screen width resolves issues related to different screen dimensions across devices. WhiteboardView has also fixed aspect ratio to 9/16 for the same reason.

Communication with Firestore

The app uses a very simple data structure in Firestore. Every whiteboard is saved in a single document consisting of content id and a list of lines. Such a structure is a result of the Firestore pricing model which is based mostly on a number of documents being read and written. Not separating whiteboard into multiple documents has some drawbacks most significant of which in this case is the limit to 1 write per second to a document. 

Whiteboard, firestore communication

New lines are saved to the database when the drawing is finished to reduce the number of writes and Firestore costs. The new content id is also added to the list of written ids to allow for comparison explained earlier.

Whiteboard content

Editing content

Adding a new line if fairly straight forward. New line is created in the onGestureStart method and stored in the _currentLine field. New points are added in the onGestureUpdate method. In onGestureEnd a line is added to the WhiteboardContent model and saved in Firestore.

Deleting lines is a bit more complex. In each onGestureStart or onGestureUpdate invocations rectangle created by current and previous pointer positions is checked for intersection with rectangles created by each two consecutive line points (or with a rectangle of size equal to double the line width centered around the point in case of only one available). If any of the rectangles created by the line section intersect line is removed from WhiteboardContent and changes are saved in the database.

Whiteboard, editing content

Optimizing Firestore

Firestore by default created indexes for each array field in a document to allow for “contains” querying. In the case of large arrays, this leads to a huge number of indexes being created which translates to higher database cost and slower write speeds. In our case “contains” query is completely useless so it’s important to disable the creation of those indexes.

Optimizing Firestore

You can find the application source code on GitHub.

Free product design tips

Join our newsletter and get insights that will change your product design perspective

or follow us

social-media-iconsocial-media-iconsocial-media-icon

Rate this article

No reviews yet!

Are you looking for custom solutions?

Read more

Lessons learned after making the first 10 commercial apps in Flutter.

We are sharing the insights after making the first 10 commercial apps within the last 24 months during which we’ve spent some 17.193,00 hours on Flutter projects.

Why Firestore, Part I: reasons to love it

Firestore & Firebase suite are great technologies. They allow us to build some features really fast. However, Firestore has also many pain points that outweigh the pros in most of the more advanced cases.

Complex animations in Flutter

Flutter ships with plenty of high-quality widgets, layouts, and themes which developers can use to speed up the whole creation process. A great example of custom widgets made in Flutter is the Placement Wheel developed for one of our clients.
logo

Case studies

Technology

Flutter

.NET Core

Related services

Mobile Apps

IT Consulting

We start in simple 3 steps

step_icon

4h long workshop

During 4h we analyze the problem, assess solution and create the product roadmap.
step_icon

Proof of concept

Within next 3 days we prepare the technical proof of concept to check if it fits business.
step_icon

Recommendation

After the POC is accomplished we prepare the recommendation on how to implement the product with the offer.

Request the 5-STARS workshop

Discover new ways to build digital product that solves real life problems in just 4h
or send us your brief at hello@leancode.pl