his coding guide is designed to help developers maintain a good standard. If developers write good code, you will get great products. So let's just right into it.
Keep Functions small
We usually limit our functions to 20 lines or less. Although this is not always possible.
Breaking up classes with many small well named functions is also a good idea.
This allow you to keep the context of information small, it helps when returning to the function or for other team mates viewing for the first time.
Break Up Components
Break up larger components into smaller sub-components. Such as screens.
These sub-components should be small (No larger than 200 lines) and simple to use.
If they are large (such as a screen view) it is good that they have their own directory.
Use small classes that are designed to ‘help’ other components.
They can be functions that do generic tasks for other components.
Usually reusable, try to keep them as functional as possible and not attached to existing state.
Keep anything logical out of UI code. Use services to do ‘actor’ related stuff.
By ‘actor’ we mean anything that seems general. For instance sending a message or signing out.
For example, API requests for authentication could be a service as it's own singleton.
Even if you think something needs doing or there could be a bug. Leave a TODO to come back too.
Don’t leave dead code or commented out code, it can confuse other developers.
Models for JSON
No matter the language always use models for JSON including request or responses.
In Flutter we use ‘json_annotation’ package to process JSON.
If you are using JS use TypeScript. We don’t use pure Duck-typed languages here they are one of the main reasons for bugs.
Arrays are evil
When saving data that would be lists of say ‘messages’ or ‘users’ always use a map of the UID and the data.
This allows you to manage the data much easier and make updates extremely easy.
Avoid arrays at all costs. There are also a few articles written on the security vunerbilities of arrays.
Throw server side errors
Use native error handling to throw errors from server side cloud-functions.
This allows us to handle errors organically on the client.
You also have no need for confusing status codes here. Only status messages.
Also allows us to monitor the functions correctly on GCP.
Await / async
On the client use Await and Async with cloud function calls.
Server throws errors you can handle them properly.
Use optionals (or non-nullables as the opposite term) when you can. They help a lot with knowning what could be null.
Optional will come in a future version of Flutter. They can already be enabled in Dart as of time of writing.
This example (right) is bad.
Escape the function as early as possible. (If something then return, etc)
Avoid nesting functions and statements as they will begin to grow and get confusing to read.
Use Redux or State manager
Use small redux state modules with self cleaning cache.
The models should be smart about data (Not saving too much offline and what is recent / relevant.)
Use small classes with small reducers to manage the app state. Not everything has to be offline.
No matter how small the project is; always start with scalability in mind.
Always return from a function early.
Never store vars that are returned early after some logic has happened. It causes bugs and is harder to read.
Separate state and UI code
Keep state and UI code separate.
UI code should only subscribe to state.
This allows you to test both of them easier.
Margins are banned
Don’t use margins in components.
Use other comports as blocks. Works better with responsive layouts.
Easier to understand how a set of components will layout if you define the padding and not the individual margins. This idea was stolen from Flutter dev.
Client only translations
Do not place translation systems in backend systems. It’s not needed.
Instead return keys that they client will use for the corresponding translations.
If you think we are wrong or have anything to add please leave a comment or contact us. We are open for opinions and changes :-)