Learn How to Create and Run Appwrite Functions With Dart
Tags: dart, appwrite, cloudfunctions, flutter
Published: 2021-03-12 08:50:19

With the popularity of Flutter, Dart has become a popular mainstream language. In this tutorial, we will learn to create Appwrite Functions using Dart. In this tutorial, we will write a storage cleaner function that will remove files older than xx days from Appwrite storage. We will leverage the official [Dart SDK](https://pub.dev/packages/dart_appwrite).

To learn more about our Dart SDK, please head over to our [Dart SDK announcement post](https://dev.to/appwrite/announcing-appwrite-sdk-for-dart-3ehc).

## What are Appwrite functions?
[Appwrite Functions](https://appwrite.io/docs/functions) are a way for you to extend and customize your [Appwrite BaaS](https://appwrite.io) functionality by executing your custom code. Appwrite can execute your custom code in response to any Appwrite system event like account creation, user login, or document update. You can also schedule your functions to run according to a CRON schedule or start them manually by triggering your function from an HTTP endpoint using the Appwrite client or server APIs.

## Prerequisites
In order to continue with this tutorial, you need to have an Appwrite console that you can access and have a project you can use to test this function. If you have not already installed Appwrite, please do so. Installing Appwrite is really simple. Based on your operating system, run one of the following commands. Installation should be done in less than 2 minutes.

### Unix
```bash
docker run -it --rm \
    --volume /var/run/docker.sock:/var/run/docker.sock \
    --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
    --entrypoint="install" \
    appwrite/appwrite:0.7.0
```

### Windows CMD
```powershell
docker run -it --rm ^
    --volume //var/run/docker.sock:/var/run/docker.sock ^
    --volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
    --entrypoint="install" ^
    appwrite/appwrite:0.7.0
```

### Windows PowerShell
```powershell
docker run -it --rm ,
    --volume /var/run/docker.sock:/var/run/docker.sock ,
    --volume ${pwd}/appwrite:/usr/src/code/appwrite:rw ,
    --entrypoint="install" ,
    appwrite/appwrite:0.7.0
```

You can also find detailed installation instructions on the Appwrite official [installation docs](https://appwrite.io/docs/installation).

## Activate Dart Functions Environment
In order for the Dart environment to be available in Appwrite Cloud Functions, you need to enable it. It can easily be done using the environment variables. In the Appwrite installation folder  find `.env` file. In the file find the environment variable `_APP_FUNCTIONS_ENVS` and there in the comma separated list add `dart-2.10` to make Dart environment available in the Appwrite Functions. After that, you can load updated configuration using `docker-compose up -d`.

## Initialize Function Project
First, create a project folder where you will create all the necessary files for your function. We will call this folder `storage_cleaner`. Inside create `main.dart` and `pubspec.yaml` files. Ensure your folder structure looks like this
```
.
├── main.dart
└── pubspec.yaml
```

## Add Appwrite Dart SDK dependency
Open `storage_cleaner` folder in your favorite text editor. Add the following code to `pubspec.yaml` file.

```yml
name: storage_cleaner
version: 1.0.0 
description: ""

environment:
  sdk: ">=2.7.0 <3.0.0"

dependencies:
  dart_appwrite: ^0.4.0

```
Here we are giving the package a name, version, description, and supporting Dart environment and dependencies.

## Write your Function
Open `main.dart` and update with the following code:

```dart
import 'dart:io';

import 'package:dart_appwrite/dart_appwrite.dart';

void main(List<String> args) async {
  // Initialise the client SDK
  Map<String, String> envVars = Platform.environment;
  final Client client = Client();
  client
      .setEndpoint(envVars['APPWRITE_ENDPOINT'])
      .setProject(envVars['APPWRITE_PROJECT_ID'])
      .setKey(
          envVars['APPWRITE_API_KEY']);

  // Initialise the storage SDK
  final storage = new Storage(client);

  int daysToExpire = int.parse(envVars['DAYS_TO_EXPIRE']);

  final res = await storage.listFiles(orderType: OrderType.desc, limit: 100);
  final data = res.data;
  final files = List.from(data['files']);
  var timestamp = DateTime.now()
      .subtract(Duration(days: daysToExpire))
      .millisecondsSinceEpoch;
  var deletedFiles = 0;
  for (final file in files) {
    if (file['dateCreated'] * 1000 < timestamp) {
      await storage.deleteFile(fileId: file['\$id']);
      print("Deleted ${file['\$id']}");
      deletedFiles++;
    }
  }
  print("Total files deleted: $deletedFiles");
}

```
The environment variables that we are accessing here are later set on the Appwrite Function's settings.

## Get the dependencies
In order to deploy this to Appwrite Functions, the dependencies need to be inside this folder itself, so we do the following to save dependencies in the current directory.

Using the terminal in the `storage_cleaner` directory,
```
$ export PUB_CACHE=.appwrite
$ dart pub get
```
This should now get dependencies and place the downloaded dependencies inside `.appwrite` folder. Ensure that your folder structure looks like this
```
.
├── main.dart
├── .appwrite/
├── pubspec.lock
└── pubspec.yaml
```

There might be other files and folders created by the Dart tool or your text editor, and you can ignore them.

## Create a Function in Your Appwrite Console
Login to your Appwrite console and open the project of your choosing. There, from the sidebar, tap on the `Functions` menu. In the functions dashboard, tap the `Add Function` button.

![add-function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pdsp2ge02wz7tn35t53p.png)
 

A dialog will be presented. Give your function a name of your choosing. We will call it `storage cleaner`. Next to the environment, we are using Dart, so we will choose Dart 2.10. Then tap create.

## Deploy Tag
Once you tap create in the above step, you are taken to the newly created functions overview page.

There are two ways to deploy your tag.

![deploy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y85yp4xc0c23wdiiqj9w.png)

### Deploy using Appwrite CLI (recommended)
You can easily deploy your functions using Appwrite CLI. If you have not already installed Appwrite CLI, please go through [these inctructions](https://appwrite.io/docs/command-line) to install Appwrite CLI. Once installed, you can run the following command from the `storage_cleaner` directory to deploy your tag.

```bash
appwrite functions createTag \
    --functionId=<id> \
    --command='dart main.dart' \
    --code='.'
```
The function id can be found at the right sidebar in the function's overview page.

### Deploy manually
You will find the ' Deploy Tag ' button at the bottom of the function's overview page. If you tap that button, you will get instructions for deploying. Switch to the `Manual` tab.

Create a tarfile first. From bash,
```bash
$ cd ..
$ tar -zcvf code.tar.gz storage_cleaner
```

Once the tarfile is ready, in the Manual tab in the deploy tag dialog, attach the code.tar.gz and in command type `dart main.dart`.

## Activate tag
Once you deploy the tag, it will be listed under tags on the `Overview` page. And there you will find the option to activate

## Adding Environments and Schedules
On the function's page, switch to the `Settings` tab from the `Overview` tab. A function can be triggered based on an event or a schedule you choose. This particular function will be scheduled. We will schedule it to run every day.

Scroll below to find the Schedule text field. There, paste a CRON Syntax for scheduling. For every day use `0 0 * * *`. 

Below that, under the `Variables` section, tap the `Add Variable` button. and add the following variables

* **APPWRITE_ENDPOINT** - Your Appwrite Endpoint (instead of localhost, use the ip address of your machine)
* **APPWRITE_PROJECT_ID** - Your Project ID
* **APPWRITE_API_KEY** - Your Appwrite API key with `files.read` and `files.write` permissions
* **DAYS_TO_EXPIRE** - Days for files to expire

Finally, tap Update.

## Verify it's working
To verify everything is working, in the Overview tab, tap the `Execute Now` button. Then visit the `Logs` tab to verify the output or errors are as expected.