In the world of modern application development, real-time interactions have become essential to create engaging and dynamic user experiences. Appwrite, a powerful backend-as-a-service platform, offers a Realtime API that enables developers to implement real-time functionality into their applications. In this tutorial, we'll explore how to integrate the Appwrite Realtime API into a Flutter app to create a real-time Rick and Morty character showcase app.
Buckle up and prepare for an exciting coding journey! We're about to dive into a world brimming with the quirky characters and uproarious escapades of Rick and Morty.
Start Building ๐จโ๐ป
Prerequisites:
Basic understanding of Flutter and Dart programming.
Appwrite Cloud Account.
Step 1: Create Appwrite Project And Add The Collection
Login to cloud.appwrite.io and click on Create project button from the dashboard. Name your project, hit the Create button, and your Appwrite project is ready. Click on the Databases menu in the navbar and create a new database. Now make the characters Collections to store data of the characters with attributes like name, species, age, image, etc. Go to settings and update permissions. This would help you to control who has what access and permissions to the docs inside the collections.
Step 2: Set Up Your Flutter Project
If you're new to Flutter, start by setting up a new Flutter project using the Flutter CLI or your preferred IDE. Absolute beginners can follow my tutorial on Setting up Flutter on your local machine.
Step 3: Add Your Flutter App As A Platform
In the Overview menu, click on Add a Platform and add the app name and package name to add the Flutter app to the project.
Step 4: Add Appwrite Dependency
Open your pubspec.yaml
file and add the Appwrite dependency to your project.
dependencies:
flutter:
sdk: flutter
appwrite: ^8.1.0
Run flutter pub get
in your project root directory to install the dependency.
Step 3: Initialize Appwrite
In your Flutter app's main.dart
file, import the required packages and initialize the Appwrite SDK.
import 'package:flutter/material.dart';
import 'package:rickandmorty/home.dart';
import 'package:appwrite/appwrite.dart';
Client client = Client();
void main() {
WidgetsFlutterBinding.ensureInitialized();
client
.setEndpoint('YOUR_APPWRITE_ENDPOINT')
.setProject('YOUR_APPWRITE_PROJECT_ID')
.setSelfSigned(status: true);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const HomePage(),
);
}
}
Replace YOUR_APPWRITE_ENDPOINT
and YOUR_APPWRITE_PROJECT_ID
with your actual Appwrite server endpoint and project ID.
Step 4: Subscribing To Realtime Data
Listen for changes in the collection using the Appwrite SDK's Realtime API and update the UI with new character details.
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:rickandmorty/main.dart';
import 'package:appwrite/appwrite.dart';
import 'package:rickandmorty/mycard.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Databases databases = Databases(client);
String databaseId = 'Your_Database_ID';
String collectionId = 'Your_Collection_ID';
late RealtimeSubscription subscription;
List<Map<String, dynamic>> items = [];
@override
void initState() {
super.initState();
loadItems();
subscribe();
}
loadItems() async {
try {
await databases
.listDocuments(
databaseId: databaseId,
collectionId: collectionId,
)
.then((value) {
var currentDocs = value.documents;
setState(() {
items = currentDocs.map((e) => e.data).toList();
});
});
for (var i in items) {
log(i.toString());
}
} on AppwriteException catch (e) {
log(e.message.toString());
}
}
void subscribe() {
final realtime = Realtime(client);
subscription = realtime.subscribe(
['databases.$databaseId.collections.$collectionId.documents']);
// listen to changes
subscription.stream.listen((data) {
log("there is some change");
// data will consist of `events` and a `payload`
if (data.payload.isNotEmpty) {
log("there is some change");
if (data.events
.contains("databases.*.collections.*.documents.*.create")) {
var item = data.payload;
log("Item Added");
items.add(item);
setState(() {});
} else if (data.events
.contains("databases.*.collections.*.documents.*.delete")) {
var item = data.payload;
log("item deleted");
items.removeWhere((it) => it['\$id'] == item['\$id']);
setState(() {});
} else if (data.events
.contains("databases.*.collections.*.documents.*.update")) {
var item = data.payload;
log("item update");
int idx = items.indexWhere((it) => it['\$id'] == item['\$id']);
log("${idx} is the index");
items[idx] = item;
setState(() {});
}
}
});
}
@override
void dispose() {
subscription.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Rick and Morty"),
),
body: items.isNotEmpty
? ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
Map<String, dynamic> current_obj = items[index];
return MyCard(current_obj: current_obj);
})
: const Center(
child: Text(
"Oops! No character to show",
),
));
}
}
Replace Your_Database_ID
and Your_Collection_ID
with the actual ID of the collection, you created for storing Rick and Morty character data.
Step 5: Custom Card Widget To Display Character Data
Create a new mycard.dart
file and define your character data card widget according to the type of data received.
import 'package:flutter/material.dart';
class MyCard extends StatelessWidget {
final Map<String, dynamic> current_obj;
const MyCard({Key? key, required this.current_obj}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
clipBehavior: Clip.antiAliasWithSaveLayer,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.lightBlue[100],
),
height: 100,
width: double.maxFinite,
child: Row(
children: [
Container(
height: 80,
width: 80,
clipBehavior: Clip.antiAliasWithSaveLayer,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(40),
color: Colors.grey
),
child: Image.network(current_obj["image"]),
),
Column(
children: [
Text(current_obj["name"], style: TextStyle(fontSize: 22),),
Text(current_obj["age"].toString()),
Text(current_obj["gender"]),
],
),
],
),
),
);
}
}
You can find the source code below ๐
Woohoo ๐
Congratulations! You've successfully integrated the Appwrite Realtime API into your Flutter app to create a real-time Rick and Morty character showcase app. With the power of Appwrite, you can easily add real-time functionality to various parts of your application, enhancing the user experience and engagement.
Remember that this tutorial provides a basic introduction to using the Appwrite Realtime API. Appwrite offers a wide range of features beyond what's covered here, so explore their official documentation for more advanced use cases and customization options.
Happy Hacking!
To learn more about Appwrite and Flutter, check out ๐
๐ Appwrite Docs