In this article, we are going to briefly introduce you to FlutterFlow, a low-code builder for mobile apps with a visual builder that lets you build cross-platform native apps with Flutter.
We will also describe how to add a powerful and scalable Backendless backend to complement a FlutterFlow frontend.
Building a mobile or web app used to be an enormous undertaking. In the past, creating apps, or digital products as they are sometimes called, required lots of technical knowledge and many months – even years – of dedicated development time.
The no-code/low-code movement has changed that. Now, with tools like Backendless and FlutterFlow, non-technical builders can learn and build apps in months or even weeks.
Ready to build beautiful and scalable apps with Backendless and FlutterFlow? Then let’s get started.
Try Backendless For Free To Power Up Your FlutterFlow App
Make your FlutterFlow app more powerful and scalable than ever by adding a Codeless Backendless backend and real-time database.
FlutterFlow is a platform that allows users to easily create and develop mobile apps without coding knowledge. The platform offers a range of pre-built projects, including templates for different types of apps such as travel apps, which users can use as a starting point for their own project.
The app’s canvas provides users with a visual interface to drag and drop widgets to create the desired layout. Users can select from a range of widgets and modify their properties, such as text size and font. FlutterFlow’s widget tree allows users to see the architecture of their app, which can be composed of multiple pages.
FlutterFlow also offers a range of features that make it easy to add functionality to your app. Users can add actions to different items and access third-party databases via API.
The platform also includes an animation editor to add animations to different elements in the app. FlutterFlow’s customization options include setting up themes, selecting language options, and integrating with GitHub and other tools.
Overall, FlutterFlow’s user-friendly interface and variety of features make it a useful platform for anyone looking to create mobile app UIs without coding knowledge.
Frontend vs Backend Development – and Why It Matters
From a high-level perspective, an application’s frontend is what the end user or customer will interact with. This may be an app on their mobile device, an interactive website, or a piece of software. The backend of an application is where long-term data is stored and much of the “heavy lifting” occurs.
An application’s speed and usability, and thus the user experience, is dependent on the processing power of the device where computations occur. Apps built with a beautiful frontend will get little traction if the app is painfully slow.
That is why it is recommended that as much of the logic as possible be stored on the backend. A typical server – including Cloud servers – contains far more processing power than a typical mobile phone, tablet, or laptop.
Similarly, the capabilities of the backend will be essential to growth and scale. Developers should be careful to disregard backend development because that is where the bulk of user experience failures occur.
A solid backend should not only include a database, but should offer the ability to create backend logic, build and access APIs, provide ample storage for files, images, and videos, and support messaging and notification systems.
Benefits of Adding a Backendless Backend and Database
We’ve now established that a successful app requires much more than just an impressive user interface. Most apps will be supported by their backend, including servers (hosting), data storage, user management, and in many cases, logic.
The more capable an app’s backend, the more effective the app and the better the user experience.
FlutterFlow states over 350k creators are utilizing their Flutter-based low-code mobile app development platform, but for all the strengths the platform offers on the frontend, it’s backend capabilities – and particularly database features – are lacking.
FlutterFlow offers fantastic low-code UI development tools. For all the strengths the platform offers on the frontend, however, it’s backend capabilities are limited.
From a feature standpoint, Backendless provides the most complete low-code backend capabilities on the market. In this article, we will discuss some of the basics – user authentication (registration and login) and database manipulation. However, that merely scratches the surface of what Backendless has to offer.
Other features your FlutterFlow app will benefit from include:
How to Integrate a FlutterFlow App with a Backendless Backend
From this point on, we will be demonstrating how to integrate FlutterFlow with Backendless. In this article, we’re going to walk you through the process of integrating several basic backend functions into your FlutterFlow app (click to jump to each section):
Note: The simplest way to access Backendless’ robust backend features is to build your frontend with Backendless as well. Be sure to check out our no-code UI Builder to see how it stacks up to FlutterFlow.
User registration opens up the entire set of user management functions in Backendless. These include session management, password management, user roles, and relating users to other data objects.
Firstly, let’s create a new page named Registration. Change the AppBar title text to User Registration so it describes the page logic.
Under the AppBar, add the Column component with two Text Fields (EmailField and PasswordField) and a Button (RegisterButton).
The Widget Tree will look like this:
Toggle the Password Field setting for the PasswordField component:
Also, add the disable options for the RegisterButton so it is inactive when the EmailField or the PasswordField are not filled:
At this point, I’ll skip the description of setting up the components style, alignment, and paddings (you can change these at your own discretion). Finally, the page layout might look like this:
So the UI is ready. Now let’s go to the registration part.
Let’s create a new POST API and name it RegisterUserAPI. Configure it with corresponding URL and headers.
For this section, we’ll skip some of the details that were previously described in the Register User section.
Create a new page named Login and change the AppBar title text to Login so it reflects the page logic.
Also, for this page we need two Input Field components (LoginField and PasswordField) and a LoginButton:
As we did with the Registration page, toggle the Password Field setting for the PasswordField component and add the disabled options for the LoginButton so it is inactive when LoginField or the PasswordField are not filled. These steps were also described in the previous section (Registration page).
Finally, the page layout might look like this:
So the UI is ready. Now let’s go to the login part.
Let’s create a new POST API and name it LoginAPI. Configure it with corresponding URL and headers:
In this section, let’s walk through how to retrieve data from your database by running a query.
Backendless Database uses a SQL-based querying system. This approach allows you to easily query your data and display exactly what you want the user to see.
We will again create a simple page named DataOperations for demonstration.
Change the AppBar title text to Data Operations so it describes the page logic.
This time, firstly, let’s define a new GET API call to retrieve data from the Backendless Person table:
Create a variable – whereClause of type String. Set the default value for this variable: objectId IS NOT NULL. This means that if we want to get all records from the table without any conditions, we’ll pass the objectId IS NOT NULL condition to the query parameters. Otherwise, the specified conditions will be passed:
Pass the whereClause variable to the query Parameter named where:
If the Person table exists in Backendless and has any records, they will be returned in the response. Otherwise, you’ll receive an error message saying that the corresponding table doesn’t exist. Notice that the whereClause value is set to objectId IS NOT NULL.
Please create the Person table in Backendless with the name (String) and age (Int) columns if it doesn’t exist.
As for our API, it is ready and we can move forward to the UI.
For the DataOperations page, create a new Page Variable personRecords of type List<JSON>. This can be done from the State Management tab of the page component:
Add the Column component with the ConditionField (TextField), FindButton and a PersonList (ListView):
Now let’s configure the PersonList component. This component will present the Person objects retrieved from Backendless.
In the Generate Dynamic Children tab of the PersonList, set the personList variable with maximum amount of records = 100 (Backendless server sets the maximum allowed value for the page size to 100 objects) and value from the personRecords variable, defined previously (we’ll populate this variable with records a little bit later):
Configure the conditional visibility for the PersonList, so it doesn’t appear when there are no records:
Return to the UI Builder and add a Column with 3 Text components (NameText, AgeText and ObjectIdText) and a Divider in the PersonList:
Configure the NameText, AgeText, and ObjectIdText components, so they represent the values from the PersonList items:
Finally, our UI layout will look like this:
As you can see, there are several rows in the PersonList. Each row will correspond to the record from the personRecords variable.
The text from the ConditionField component will be used as the condition for querying data from Backendless when the FindButton is pressed. So let’s finally add the logic to the FindButton On Tap action:
1. Call the PersonFind API and pass the whereClause value from the ConditionField. The result of the request will be set to the findResult variable:
2. After the PersonFind API is called we receive its response. It could be successful (3) or failed (4).
3. If the response is successful, we set the response array to the personRecords variable:
4. If the server returned an error trying to retrieve objects (e.g. the Person table doesn’t exist), the failure alert is shown with the error text received in the findResult:
Now the FindButton On Tap action is configured and we can move to the tests.
Return to the UI Builder page and press the “Run your app in Test Mode” button. Please note that the API won’t work in the Preview mode.
Wait until the test session is loaded, enter (optionally) the condition value and click Find:
If the API call was successful, we will see a list of records, retrieved from Backendless:
If an error occurred (e.g. using invalid condition), we will receive the following notification:
As the data retrieval is ready, we can now move on to object creation.
In this section, we’ll take a look at how to save data into our Backendless Database from FlutterFlow.
Create a new page named PersonPage. This page will contain logic to create (and later, edit) a Person object.
Return to the DataOperations page and add a new IconButton named CreatePersonButton:
This button will navigate us to the PersonPage without any parameters – just for creating a new Person.
Also, we’ll clear a personRecords variable here, so the On Tap action has this behavior:
Let’s go back to the PersonPage and create a Page variable – titleText of type String:
Change the AppBar style to the one that contains the back button (so you can return to the previous page) and set the AppBar title to the titleText variable.
For the page, add an On Page Load action and set the titleText variable value to “Create a new Person” (this title can be different in the future, but we’ll return to it in the following sections):
Also, for this page we need two Input Field components (NameField and AgeField) and a SaveButton:
Modify the disabled state option for the Save button (it should be disabled when the NameField or AgeField is not filled):
Now it’s time to add a new POST API to create a new Person. Configure it as shown below:
Also create two variables – name of type String and age of type Int – that will be passed to the body of the Backendless Saving Single Object API:
Pass these variables to the request body:
Now the PersonSave API is ready to be tested. Go to the Response & Test tab, enter the test name and age values and run the API:
The API works correctly and the created Person object is returned with status 200 as expected.
Now we can move forward to the SaveButton actions. Create a new On Tap action and configure an Action Chain that looks like this:
1. Call the PersonSave API and pass the name and age values from the NameField and AgeField. The result of the request will be set to the saveResult variable:
2. After the SaveAPI is called we receive its response. It could be successful (3) or failed (5).
3. If the response is successful, we’ll see an alert with a success message “Object was successfully saved in Backendless. You will be redirected to the Data Operations page.”:
4. After the alert is closed, we are automatically redirected back to the Data Operations page.
5. If any error occurred while saving a new Person object, an error alert will appear with the error text received in the saveResult. As usual, we will display only the message from the error (as we did in the previous section), not the whole object. This can be done by using the Custom JSON Path name:
6. Finally, we clear the NameField and AgeField components:
Now the SaveButton On Tap action is configured and we can move to the tests.
Return to the UI Builder, select the DataOperations page, and press the “Run your app in Test Mode” button. Please note that the API won’t work in the Preview mode.
Wait until the test session is loaded, enter the condition, review the records matching the criteria, and click the Add New Person button to open the PersonPage:
Fill the Name and Age in the corresponding fields and click Save:
If everything is ok, the success message will appear:
You can now press the Back button to return to the previous DataOperations page. Enter the condition again and you’ll see a newly created record:
Now when we’ve finished with creating a new object in Backendless, we can move forward to editing the existing objects.
Take a look at the next section to learn how to update or delete an object.
Now that we’ve learned out how to create a new object in Backendless, it will be easier to understand process of object editing. We can use the existing PersonPage for this.
Firstly, let’s add the personObject to the PersonPage parameters:
This parameter will be passed from the Data Operations page and will be used to identify an object we want to update or delete.
Return to the DataOperations page, select the PersonList Column and add the On Tap action:
1. Navigate to the PersonPage. Here we’ll pass the selected PersonList Item as the personObject:
2. Clear the personRecords list:
We’re finished with the DataOperations page and now can work directly with the PersonPage.
On the PersonPage, change the On Page Load action to follow the condition:
1. Check if the personObject is set.
2. If the personObject is set on page, set the titleText value to “Edit Person”:
3. Otherwise, set the titleText value to “Create a new Person”:
For the NameField and AgeField set the Initial Values if the personObject is set:
Also add the Icon Button (DeleteButton) on the PersonPage, so finally the page may look like this:
Now let’s add a new PersonUpdate PUT API call. Configure it as shown below:
Create an objectId variable of type String that will be passed as a dynamic parameter to the Backendless Update Single Object API url. Also, create two variables – name of type String and age of type Int – that will be passed to the body of the request. These are the parameters we would have an ability to change in the Person object:
Pass the name and age variables to the request body:
Now the PersonUpdate API is ready to be tested. Go to the Response & Test tab, enter test name, age, and objectId values (choose any Person object in your database to test with) and run the API:
The API works correctly and the updated Person object is returned with status 200 as expected. Notice that objectId value is the id of the existing object in Backendless Database.
Now we can move forward to the SaveButton actions. Edit the existing On Tap action to look like this:
1. Check if the personObject is set.
2. If the personObject is set, call the PersonUpdate API:
Pass the name and age values from the NameField and AgeField (like we did when creating a Person in the previous section). Also, pass the objectId value taken from the personObject:
3. After the PersonUpdate API is called, we receive its response. It could be successful (4) or failed (5).
4. If the response is successful, we’ll see an alert with a success message “Object was successfully updated in Backendless.”:
5. If any error occurred while updating a Person object, an error alert will appear with the error text received in the updateResult. As usual, we will display only the message from the error (as we did in all previous sections):
6. If the personObject is not set, a new object will be created. The steps 6-10 are the same as the saving steps 1-5 from the previous section – we call the PersonSave API to create a new Person and return to the DataOperations page if the creation was successful.
We’ve finished the object update functionality and now it’s time to implement the object deletion.
Add a new DELETE API call called PersonDelete and configure it:
To pass the objectId parameter to the URL, add it in the Variables tab:
Go to the Response & Test tab, enter the objectId of the existing Backendless object, and run the API:
The API works correctly and returns the deletion timestamp with status 200 as expected.
Add the On Tap action for the DeleteButton:
1. Firstly a Confirmation Dialog is shown. User is asked if he/she is really want to delete an object:
2. If the user confirms the object deletion, the PersonDelete API (3) is called.
3. Otherwise, the dialog just closes without any further actions.
4. After the PersonDelete API is called, we receive its response. It could be successful (5) or failed (6).
5. If the response is successful, we’ll see an alert with a success message “Object was deleted from Backendless. You will be redirected to the Data Operations page.”.
6. After the alert is closed, we are automatically redirected back to the Data Operations page.
7. Otherwise, an error alert will appear with the error text received in the saveResult.
Now the SaveButton and DeleteButton On Tap actions are configured and we can move to the tests.
Return to the UI Builder, select the DataOperations page, and press the “Run your app in Test Mode” button. Please note that the API won’t work in the Preview mode.
Retrieve the records from Backendless and click on any item:
You will be redirected to the PersonPage. Edit the Person age
and click Save. If everything is fine, you’ll see a corresponding message:
Now click the Delete Button:
and confirm the object deletion.
You’ll receive a message after the object is deleted:
And will be redirected to the Data Operations page.
In the final part of this article, let’s look at sending emails with templates.
Firstly, open Backendless Console and configure the Email Settings to enable the Email Delivery API. Then create a simple Email Template to test the functionality.
Now we can switch back to FlutterFlow.
Create a new Page named EmailTemplate, change the AppBar title and add a column with two TextField components (TemplateNameField and EmailsField) and a Button (SendButton):
So the page layout should look like:
The email addresses can be filled in the corresponding field separated by comma.
Let’s add a new API to send emails and name it SendEmailWithTemplate:
Also let’s create two variables – templateName of type String and addresses of type List<String> that will be passed to the body of the Send Emails with Templates API:
Pass these variables to the request body:
As you might have noticed, the addresses parameter is a List of Strings and the value from the EmailsField is a type of String, so we need the ability to parse the string value to the list.
Let’s create a simple custom code split() function for this:
The split() function takes a String variable named input as a parameter and returns a list, created from this input parameter separated by commas.
Now we can configure the On Tap action for the SendButton.
Add the Button disabled options:
So the button is disabled if any of the input fields are empty.
Now add the On Tap action with the actions chain:
1. Сall the SendEmailWithTemplate API and pass the templateName and addresses values:
The result of the request will be set to the emailResult variable.
As you can see, the addresses parameter value is the value from the EmailsField, split to the array using the split function:
2. After the SendEmailWithTemplate API is called, we receive its response. It could be successful (3) or failed (5).
3. If the response is successful, an alert with an “Email was sent successfully. Please check your email box.” message is shown:
4. After the successful alert is closed both text fields are cleared:
5. Otherwise, the failure alert is shown with the error text received in the emailResult:
The SendButton On Tap action is configured and we can now test how Sending Email with Template works.
Return to the UI Builder page and press the “Run your app in Test Mode” button. Wait until the test session is loaded, enter a template name an email (or emails separated by commas) and click Send:
If the email was sent successfully, we will receive a message about success:
And the email appears in your email inbox:
Otherwise, if the error occurred (e.g. user entered incorrect template name), the error message will appear:
Conclusion
You should now have a basic handle on how to interact with a Backendless backend via FlutterFlow, but this is just the tip of the iceberg. Adding a Backendless backend and database to a FlutterFlow mobile app gives your app incredible flexibility.
With FlutterFlow’s easy frontend interface and Backendless’ many pre-built APIs, your possibilities become endless.
In addition to managing users and data, Backendless gives you access to Cloud Code timers, event handlers, and whatever Codeless logic you can think of on the backend.
Learn the ins and outs of Backendless Database, our robust and scalable visual relational DB, with this free video course from Backendless CEO Mark Piller. New videos released weekly, so leave your feedback to shape future parts!
Thunkable is a no-code app builder specializing in iOS and Android mobile apps. When you integrate a feature-rich no-code Backendless backend with your Thunkable app, you get a visual relational database, user management, bulletproof security, highly-scalable serverless hosting, and much more.
In the software as a service (SaaS) landscape, there are many variations of “____ as a service”. In this article, we will explain what mobile backend as a service, or MBaaS, means.