Flutter Appwrite — The Complete Crash Course
Appwrite is a self-hosted backend solution, that has gained more and more popularity over the last months. It can be handy for personal and commercial Apps and provides great features. In this article, you will learn how to use Appwrite and see, that it is one of the easiest-to-use backend solutions in Flutter.
Happy reading!
Installation
The first thing we have to do after creating our app is to add appwrite
. To do so, we will use the command flutter pub add appwrite
.
But that’s not all. Because Appwrite is a backend solution, we have to download it on our machines. If you use Digital Ocean or Gitpod, click on the links here to do a One-Click Setup.
If you don’t use one of these both, you can install it with Docker. Click here to do so. If you haven’t docker installed yet, you can install it here.
Create Appwrite project
Now, let’s set up an Appwrite project. Make sure that your docker CLI is running, so you can access the Appwrite dashboard via localhost
. If you are using Appwrite Cloud, just head to your Appwrite Cloud dashboard.
There, click on Create Project
. Follow the instructions there and click on Create. Now we have to add a new Flutter platform to your project. In the project you have created, click “Add Platform”. Choose Flutter and add your App credentials.
If you are building your app for different platforms, you need to do some steps for each platform. Here are all the links for that:
Android
iOS
Linux
macOS
Web
Windows
Your First Steps & User auth
Let’s start by initializing your SDK. To do so, go to the Settings in your Appwrite Dashboard to get the Project ID and the Endpoint.
Import Appwrite and create a new variable of type Client
. Now you can set the endpoint and your localhost:
import 'package:flutter/material.dart';
import 'package:appwrite/appwrite.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
Client client = Client()
.setEndpoint("https://localhost/v1") // If you are using Appwrite cloud, use https://cloud.appwrite.io/v1
.setProject("<YOUR_PROJECT_ID>");
runApp(MaterialApp();
}
Now, let’s make our first request. We will create an account. To do so, we create a new variable called account
and call .create()
. We can specify some things there, that you can get from your text fields:
// Create account variable
Account account = Account(client);
// Create a new account. name is optional
await account.create(
userId: ID.unique(),
email: email,
password: password,
name: name,
);
But this only creates the account, not log in the user. If you want to log the user in, we can use createEmailPasswordSession
:
// Login
await account.createEmailPasswordSession(email: email, password: password);
// Get the user. Save it somewhere in your state management to access it, e.g. a userProvider
final user = await account.get();
If we want to log out the user, we can call deleteSession()
(Don’t worry, it does not delete the account, just the current session):
await widget.account.deleteSession(sessionId: 'current');
But what if you want to delete an account? This is not that simple, because we have to work with the User API (not the Account API). The user API is integrated from the server side and operates in an admin scope, while the Account API operates in the scope of the currently logged-in user and usually uses a client-side integration. Because Appwrite supports server-side Dart SDK code, we can still use our Dart code but have to add the package dart_appwrite
. Additionally, we then need to deploy the function and get the response of it. I am not going to cover it here, as this is a beginner Appwrite tutorial. But our basic code would look like this:
import 'package:dart_appwrite/dart_appwrite.dart';
Client client = Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2'); // Your secret API key
Users users = Users(client);
await users.delete(
// We'd get the user id from the arguments passed to the function
userId: '<USER_ID>',
);
// We would need to return a response obviously
Using Databases
To create your Database, head back to your project and navigate to “Database”. Create your database there. Every database is split into collections. You don’t have to create multiple databases for your apps, but it’s recommended for bigger applications. Inside a collection, you can add different Attributes. In a To-do list application, it’s for example the date, text, and a bool if it’s completed. You don’t have to specify the UserID there if you set your permissions to “Document Level” in the Settings of your collection. In addition, you don’t have to worry about an ID, because Appwrite automatically assigns IDs (without any attribute you have specified).
But now, we want to get the database entries of course. First, we will list all the documents:
final databases = Databases(client);
try {
final documents = await databases.listDocuments(
databaseId: '<DATABASE_ID>',
collectionId: '[COLLECTION_ID]',
queries: [
// No queries means everything. Read more about queries here: https://appwrite.io/docs/products/databases/queries
]
);
} on AppwriteException catch(e) {
print(e);
}
You can get the Collection ID in the Settings of your collection and the Database ID in the Settings of your Database.
But what if the user clicks on a to-do and wants to access all its information? Then we have to get only one entry. This is also very easy with Appwrite:
try {
Document result = await databases.getDocument(
databaseId: '<DATABASE_ID>',
collectionId: '<COLLECTION_ID>',
documentId: '<DOCUMENT_ID>',
);
} on AppwriteException catch(e) {
print(e);
}
We get all the documents, but the user hasn’t created any documents yet. So let’s do this right now:
try {
Document result = await databases.createDocument(
databaseId: '<DATABASE_ID>',
collectionId: '<COLLECTION_ID>',
documentId: '<DOCUMENT_ID>',
data: {
"text": "Go for a walk",
"done": false,
// ...
},
permissions: ["read("any")"], //read more about permissions
);
} on AppwriteException catch(e) {
print(e);
}
Further reading & Conclusion
In this article, you have learned the basics of the backend solution “Appwrite”. You have seen how helpful it can be and how easy it is to use. In my opinion, Appwrite is the easiest-to-use backend solution among Firebase, AWS, and Supabase.
Please notice that this is only a very brief overview of Appwrite and does not cover everything. There is so much more to discover. If you want me to write a more advanced article, just leave a comment!
In the meantime, head to Appwrite’s documentation: https://appwrite.io/docs
In the following few articles, I will introduce more somewhat complicated packages and explain them. If you don’t want to miss this, I recommend you to follow me. I tried my best to write the easiest tutorial that everyone understood. If you appreciate this work, I would be very grateful if you could support this quality content and give me some claps!
Thanks for reading, have a nice day!