构建 Flutter 后端分步指南
本文将讨论 Flutter,这是 Google 开发的一款开源 UI 软件开发工具包。
我们将探讨使用 Flutter 的优缺点,并重点介绍 Flutter 应用程序的不同后台选项。
最后,您将学习如何使用 Back4apps 的后端即服务(BaaS)功能为 Flutter 应用程序构建一个可用的后端。
Contents
什么是Flutter?
Flutter 是一个跨平台开发框架,可让您快速构建原生感的 Android、iOS、Web、Linux、macOS 和 Windows 应用程序。
有了 Flutter,您会发现构建特定平台应用程序的许多复杂问题都迎刃而解了。Flutter 还以其快速的性能和漂亮的 UI 部件而闻名。
Flutter 团队自己将这项技术定义为
Google的一个开源框架,用于从单一代码库中构建美观的、本地编译的多平台应用程序。
Flutter 的三大优势和局限
优势 | 局限性 |
---|---|
Flutter 是一个快速框架,具有大量即用型功能,可帮助您加快应用程序的开发时间。 | Flutter 应用程序往往比使用 React Native 等其他框架构建的应用程序更大。 |
Flutter 应用程序是跨平台的,可在 Android 和 iOS 上运行,为您节省开发时间和资金。 | Flutter 是一个相对较新的框架,社区规模相对较小。这可能会使您在需要时很难找到帮助和支持。 |
Flutter 易于学习,即使是初学者也不例外。精彩的文档让你轻松上手。 | Flutter 使用 Dart 编程语言,这种语言不像 Java 或 JavaScript 等其他语言那样广为人知。这可能会限制您可用的软件包。 |
后台类型有哪些?
在构建任何应用程序时,选择正确的后台选项来处理服务器端任务都是非常重要的。
每种类型的后端都有自己的强项,您的应用程序的特定需求应指导您选择后端。
下面的小节将重点介绍你可以使用的不同后台选项、它们是什么、如何工作以及它们如何最适合你的应用程序的需要。
IaaS
如果您要处理的是一个拥有众多用户的大型应用程序,那么IaaS是您应该考虑采用的后端选项。IaaS 是一种云计算模式,代表基础设施即服务。
云计算是一种由第三方供应商通过互联网提供计算资源(如服务器、存储和应用程序)的模式。
这些资源可按需访问,按需付费。使用 IaaS,云提供商将维护主要的底层计算基础设施,而您则可以完全控制应用程序的数据配置、操作系统和所有其他后端要求。
这使它成为需要增加或减少计算资源的应用程序的良好后端选择。
PaaS
平台即服务(PaaS)和基础设施即服务(IaaS)是两种不同的云计算模式,各有不同的用途。虽然二者都具有灵活性和可扩展性,但它们在开发和部署应用程序方面满足了不同的需求。
PaaS 后端将为您提供完整的开发环境,抽象出管理服务器、网络和存储的复杂性。如果您想专注于构建和维护应用程序,而无需担心基础设施管理,那么 PaaS 将是您的最佳选择。
BaaS
后端即服务(BaaS)后端可为您提供随时可用的后端服务和功能,使他们能够专注于构建和增强应用程序的用户体验,而无需管理后端基础设施。
有了 BaaS,开发人员可以通过应用程序接口访问用户验证、数据库和存储等功能,无需设置和维护后端服务器。
这就像使用一块现成的拼图,完全适合您的应用程序,省时省力。
从本质上讲,BaaS 简化了开发流程,使开发人员能够专注于应用程序面向用户的方面,同时依靠预构建的后端服务来处理繁重的工作。
如何使用后端即服务构建 Flutter 后端
本节将讨论如何开始构建 Flutter 应用程序的后端。Back4app 平台是构建可扩展、安全、灵活且易于部署的后端应用程序的绝佳选择。
Back4app 概览
Back4App 是一个后台即服务(BaaS)平台,通过提供完整的后台基础设施简化移动和网络应用程序开发。
使用 Back4App,您就可以专注于构建应用程序的前端功能。
该平台提供各种随时可用的后端服务,包括数据库、应用程序接口和云功能。
Back4app 的主要功能/优势包括
- 关系数据库和非关系数据库
- REST 和 GraphQL 应用程序接口
- 实时查询
- 多种认证选项
- 可扩展托管
- 推送和电子邮件通知
Back4App 使用 Parse 服务器,这是一个用于开发应用程序服务器端组件的开源工具包。支持多种技术。本参考指南列出了 Back4app 支持的不同技术。
项目介绍
本指南旨在构建一个 Back4app 后端,以支持 Flutter 应用程序。应用程序将使用 Parse 服务器 SDK 与设置好的后端进行连接和交互。
您要创建的应用程序是一个简单的联系人应用程序,允许用户创建和读取联系人。这些联系人将使用 Back4app 的 PostgreSQL 数据库支持进行存储。
用户只需在应用程序中输入联系人信息,即可添加新联系人。
在本指南结束时,您将对如何做有一个扎实的了解:
- 在 Back4app 平台上构建后端应用程序
- 写入结构化的 Back4app 数据库
- 处理 Parse 后台安全的基础知识。
先决条件
要学习本指南,您必须满足以下前提条件:
- 熟悉 Dart 语言和 Flutter 框架
- 在 Flutter 中操作状态的知识
- 运行应用程序的设备模拟器或模拟器。iOS 的 Xcode 或 Android 的 Android Studio。
- 基本了解关系型和非关系型数据库
创建应用程序
您需要有一个 Back4app 帐户来创建您的后台。如果您没有账户,可以通过注册免费的 账户来创建。
如果您已经拥有 Back4app 账户,请登录并创建新应用程序。选择 “后台即服务 “作为服务选项。
这将构建一个可扩展的 BaaS 后端。别忘了给你的应用程序起一个唯一的名字。对于数据库的选择,Back4app 提供 PostgreSQL 作为数据库选项。
PostgreSQL 是一种流行的开源关系数据库管理系统(RDBMS)。它以可扩展性、可靠性、高性能和安全性著称。
使用 Back4app 中的 PostgreSQL 测试版选项,您就可以利用这些功能和优势。
构建阶段应该很快结束。完成后,您将进入应用程序仪表板。
PostgreSQL 数据库
在 Back4App 中,您可以定义表示应用程序数据的类和字段。PostgreSQL 使用关系数据库,这是一种为应用程序用户存储数据的结构化方法。
如前所述,我们的 Flutter 应用程序将是一个联系人簿,可以存储多个联系人。PostgreSQL 数据库保存关系。该应用程序的合理数据模型是联系人类和联系人的城市邮编。
让我们从联系人模型开始。联系人表需要不同的字段;
- 联系人 ID/对象 ID
- 名称
- 电话号码
- 邮政编码
您的数据模型表将如下所示;
联系方式
现场 | 数据类型 | 制约因素 |
---|---|---|
contactId | 整数 | 主键 |
名字 | 字符串 | 非空 |
电话号码 | 整数 | 非空 |
邮政编码 | POINTER | 非空 |
邮政编码
现场 | 数据类型 | 制约因素 |
---|---|---|
对象标识 | 整数 | 主键 |
邮政编码 | 整数 | 非空 |
联系人对象将存储联系人信息,并以contactId作为主键。姓名、电话号码和邮政编码字段必须填写(NOT NULL)、
该数据模型在联系人应用的表之间创建了一种关系,使您能够管理联系人信息,并将多个字段与每个联系人关联起来。
要在 Back4app 应用程序上创建这两个班级,请点击控制面板左上角的 “创建班级“按钮。
将类别命名为 “联系人”,并将 “是否为必填字段“选项切换为 “打开”。
为Contact 中的数据字段创建列,然后为ZipCode类创建同样的列。Back4app 允许您自定义创建的每一列。
管理面板
Back4App 提供直观的 GUI(图形用户界面),称为管理面板,可轻松管理应用程序的后台。
管理面板是监控、编辑和分析数据的强大工具,是应用程序管理的宝贵资产。
您可以在应用程序中访问应用程序的管理面板。在应用程序的仪表板上,您会在 “更多“下找到一个标有“管理面板“的按钮或链接,它将引导您进入管理面板。您可以在那里切换并启用管理应用程序。
您将提供一个用户名和密码来访问管理应用程序。
设置管理应用程序的最后一步是选择一个用于访问面板的域名。
在本指南中,一个很好的例子是:flutter-backend.admin.back4app.com。
现在,您可以在浏览器上打开提供的域,登录管理仪表板。
要了解有关 Back4app 管理应用程序的更多信息,请访问官方文档。
确保应用程序的安全
目前,您的后台应用程序是完全脆弱的,其中的信息可以从客户端进行篡改。
为了防止在生产阶段出现这种情况,可以配置相关规定和访问权限。
要控制类的创建方式并禁止从客户端创建类,请导航至控制面板>应用程序设置并找到客户端类创建。将此选项切换为关闭,因为您的应用程序目前只需要您创建的两个类。
切换关闭时会出现一个弹出窗口。这是为了确认和保存应用程序的更改。
使用 Flutter 进行 CRUD API 测试
在本节中,您将使用自己构建的 Flutter 应用程序测试应用程序的后台 API 功能和数据库。首先,您将为 Flutter 应用程序构建用户界面。
您必须在计算机上安装 Flutter SDK 才能初始化 Flutter 应用程序。
按照Flutter 的官方 入门 文档,在 Windows 或 Mac 机器上安装 Flutter SDK 和构建 Flutter 应用程序所需的工具。
要初始化 Flutter 应用程序,请在终端中运行以下命令:
#Initialize your Flutter app
flutter create my_flutter_app
#Run your Flutter app
flutter run
这些命令将搭建并启动一个简单的 Flutter 应用程序,供您构建。
为了保持本指南的简洁性,main.dart
文件将包含运行 Flutter 应用程序的大部分代码。我们不会在此讨论 Flutter 代码,因为这不是本指南的目的。
用以下代码覆盖main.dart
中的所有代码:
import 'dart:ffi';
import 'package:flutter/material.dart';
import 'package:parse_server_sdk_flutter/parse_server_sdk_flutter.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final keyApplicationId = 'appID';
final keyClientKey = 'clientKey';
final keyParseServerUrl = '<https://parseapi.back4app.com>';
await Parse().initialize(keyApplicationId, keyParseServerUrl,
clientKey: keyClientKey, debug: true);
runApp(MaterialApp(
title: 'Contacts',
theme: ThemeData(
primaryColor: Colors.white,
),
home: ContactsApp(),
));
}
class ContactsApp extends StatefulWidget {
const ContactsApp({Key? key}) : super(key: key);
@override
// ignore: library_private_types_in_public_api
_ContactsAppState createState() => _ContactsAppState();
}
class _ContactsAppState extends State<ContactsApp> {
List<Contact> contacts = [];
String? selectedZipCode; // Initialize with a default value
@override
void initState() {
super.initState();
selectedZipCode = '1234'; // Initialize with a default value
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Contacts'),
),
body: ListView.builder(
itemCount: contacts.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(contacts[index].name),
subtitle: Text(contacts[index].phoneNumber),
trailing: IconButton(
icon: const Icon(Icons.delete),
onPressed: () {
setState(() {
contacts.removeAt(index);
});
},
),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_showAddContactDialog();
},
child: const Icon(Icons.add),
),
);
}
void _showAddContactDialog() async {
showDialog(
context: context,
builder: (context) {
String name = '';
String phoneNumber = '';
return AlertDialog(
title: const Text('Add Contact'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
decoration: const InputDecoration(labelText: 'Name'),
onChanged: (value) {
name = value;
},
),
TextField(
decoration: const InputDecoration(labelText: 'Phone Number'),
onChanged: (value) {
phoneNumber = value;
},
),
// Checkbox for Zip Code
ListTile(
title: const Text('Select Zip Code'),
subtitle: Column(
children: [
RadioListTile(
title: const Text('1234'),
value: '1234',
groupValue: selectedZipCode,
onChanged: (value) {
setState(() {
selectedZipCode = value;
});
print(selectedZipCode);
},
),
RadioListTile(
title: const Text('4321'),
value: '4321',
groupValue: selectedZipCode,
onChanged: (value) {
setState(() {
selectedZipCode = value;
});
print(selectedZipCode);
},
),
],
),
),
],
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('Cancel'),
),
ElevatedButton(
onPressed: () async {
setState(() {
contacts.add(Contact(
name: name,
phoneNumber: phoneNumber,
zipCode: selectedZipCode as String,
));
});
// Save the contact to Back4App
final contact = ParseObject('Contact');
contact.set('name', name);
contact.set('phoneNumber', phoneNumber);
contact.set(
'zipCode',
(ParseObject('ZipCode')..objectId = selectedZipCode.objectId)
.toPointer());
await contact.save();
// ignore: use_build_context_synchronously
Navigator.of(context).pop();
},
child: const Text('Save'),
),
],
);
},
);
}
}
class Contact {
final String name;
final String phoneNumber;
final String zipCode;
Contact({
required this.name,
required this.phoneNumber,
required this.zipCode,
});
}
class ZipCode {
final String zipCode;
ZipCode({
required this.zipCode,
});
}
这样,您的 Flutter 应用程序的基本 UI 就可以运行了。
现在你可以开始实施 Back4app 了。Back4app 使用 Parse Flutter SDK 将 Parse 服务器集成到 Flutter 应用程序中。
Parse Server 是一个开源后端平台,为管理应用程序数据提供了一个即用型基础架构。
有了 SDK,您就可以通过 Flutter 应用程序与 Parse Server API 通信,从而更轻松地对数据执行 CRUD 操作(创建、读取、更新、删除)、管理用户会话以及处理其他服务器端功能。
要使用 Parse SDK,请将其作为依赖项安装到 Flutter 项目的pubspec.yaml
文件中。
指定Parse服务器:
dependencies:
# Parse SDK
parse_server_sdk_flutter: ^5.1.1
flutter:
sdk: flutter
确保缩进准确。.yaml
文件对大小写和缩进非常敏感。
运行命令安装指定的依赖项:
flutter pub get
前往main.dart
,导入添加的 Parse SDK:
import 'package:parse_server_sdk_flutter/parse_server_sdk_flutter.dart';
void main() async{
WidgetsFlutterBinding.ensureInitialized();
// code for runApp()
const keyApplicationId = 'YOUR_APPLICATION_ID_HERE';
const keyClientKey = 'YOUR_CLIENT_KEY_HERE';
const keyParseServerUrl = '<https://parseapi.back4app.com>';
await Parse().initialize(keyApplicationId, keyParseServerUrl,
clientKey: keyClientKey, debug: true);
}
在这里,你要将 ParseSDk 导入你的main.dart
文件。你还需要在main()
中调用Parse().initialize()
来初始化Parse。由于这是一个异步程序,所以要用 async 关键字标记main()
。
必须用实际值替换Application_Id和Client Key的占位符。这些是与后端通信的应用程序凭据。
要获取这些密钥,请从 Back4app 面板导航至应用程序设置>安全与密钥。然后用相应的密钥替换占位符。
运行应用程序时,main()
将被触发,Parse 将初始化您的应用程序,您的 Flutter 应用程序将连接到 Back4app 后端。
写入联系人和邮政编码类
在这里,您将学习如何从应用程序的客户端创建数据库中的类并写入这些类。要创建 “联系人 “和 “生日 “类,您需要修改main.dart
文件。
在高架按钮部件的onPressed()
方法中,您将使用ParseObject()
创建一个联系人 类的新实例:
final contact = ParseObject('Contact');
contact.set('name', name);
contact.set('phoneNumber', phoneNumber);
final ParseResponse parseResponse = await contact.save();
if (parseResponse.success) {
final contactId = (parseResponse.results!.first as ParseObject).objectId!;
print('Object created: $contactId');
} else {
print('Object created with failed: ${parseResponse.error.toString()}');
}
Parse Flutter SDK 会使用ParseObject()
创建一个新实例,该实例与您作为参数传递的类名相同。使用对象字段的名称及其值调用Contact.set()
将写入并更新这些字段。
您可以创建一个ParseResponse
对象来保存保存操作的结果。ParseResponse
将包含一个success
属性,如果保存操作成功,则该属性为true
;如果保存操作失败,则该属性为false
。
然后,代码会将变量contactId
初始化为空。该变量将用于存储自动生成的已保存联系人对象的objectId
。然后进行一些错误处理。
在上述代码下方
final zipCodeObject = ParseObject('ZipCode')
..objectId = selectedZipCode as String;
zipCodeObject.set('zipCode', selectedZipCode);
contact.set('zipCode', zipCodeObject.toPointer());
await contact.save();
await zipCodeObject.save();
在此创建邮编 ParseObject。当通过对话框添加新联系人时,代码将正确创建一个ZipCode
对象,并将其与联系人
对象的zipCode
字段关联。
它使用所选邮编的objectId
作为指针建立关联。使用.
save()
方法将两个对象保存到后台。
从数据库中查询/读取数据
下面我们将讨论如何从 Flutter 应用程序向数据库发送查询。您可以进行查询,检索具有相同邮政编码的所有联系人。在非关系型数据库系统中,要实现这一点相当复杂。
如果检索成功,就可以显示 Flutter 应用程序中所有联系人的列表。
检索具有相同邮政编码的联系人列表:
Future<void> _loadContacts() async {
final queryBuilder = QueryBuilder<ParseObject>(ParseObject('Contact'))
..whereEqualTo('zipCode', selectedZipCode) // Filter by zip code
..orderByAscending('name');
final response = await queryBuilder.query();
if (response.success && response.results != null) {
final List<Contact> loadedContacts = response.results!.map((parseObject) {
return Contact(
name: parseObject.get('name'),
phoneNumber: parseObject.get('phoneNumber'),
zipCode: parseObject.get('zipCode')!.objectId,
);
}).toList();
setState(() {
//set your contacts to loadedContacts
});
}
}
@override
void initState() {
super.initState();
_loadContacts(); // Load contacts when the app starts
}
_loadContacts
方法向联系人
类建立一个查询,查找具有指定邮政编码的联系人对象。
然后,该方法会返回联系人列表,同时根据 “姓名 “字段按姓名升序排列。
应用程序启动时(initState
),会调用_loadContacts
方法来获取所选邮编的联系人。
结论
拥有一个可控的后端绝对是必要的,在这里您可以正确构建应用程序中的数据流。使用 Back4app,您可以随时随地建立移动应用程序的后台。
您还可以使用 Back4app 平台,通过设置用户模型数据库来实现用户身份验证。
什麼是 Flutter?
Flutter 是一個開發框架,可用於建立跨多個平台的類原生應用程式。它簡化了建立特定平台應用程式的流程,並以快速的開發速度和漂亮的使用者介面而聞名。
後端部署有哪些選項?
– IaaS(基礎設施即服務)
– PaaS(平台即服務)
– BaaS(後端即服務)
如何建立一個 Flutter 應用的後端?
1. 規劃應用程式的資料模型結構
2. 設置一個資料庫來對應這個結構
3. 撰寫 UI 檢視邏輯並連接後端
4. 測試後端的安全性漏洞並執行 CRUD 操作
5. 選擇一個部署平台,例如 Back4app
6. 將你的應用程式部署到後端