万物皆可Serverless系列文章
- 万物皆可Serverless之免费搭建自己的不限速大容量云盘(5TB)
- 万物皆可Serverless之使用云函数Timer触发器实现每天自动定时打卡
- 万物皆可Serverless之使用SCF COS快速开发全栈应用
- 万物皆可Serverless之使用SCF COS免费运营微信公众号
- 万物皆可Serverless之使用SCF快速部署验证码识别接口
- 万物皆可Serverless之Kaggle SCF端到端验证码识别从训练到部署
- 万物皆可Serverless之借助微信公众号简单管理用户激活码
- 万物皆可Serverless之使用SCF COS给未来写封信
- 万物皆可Serverless之在Flutter中快速接入腾讯云开发
- 万物皆可Serverless之在Flutter中写一个Dart原生腾讯云对象存储插件
- 万物皆可Serverless之我的Serverless之路
一、本文介绍
云开发(Tencent Cloud Base,TCB)是腾讯云为移动开发者提供的高可用、自动弹性扩缩的后端云服务,包含计算、存储、CDN、静态托管等能力(Serverless 化),可用于开发多种端应用(小程序,公众号,Web 应用,Flutter 客户端等,后续会陆续支持 iOS 和 Android 等移动应用开发),达到一站式后台服务构建多端应用,帮助开发者统一构建和管理后端服务和后端云资源,避免了应用开发过程中参与繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
这是腾讯云官方文档的里的关于云开发的简介,
本文将带领大家按照云开发的官方文档在Flutter中快速接入一下腾讯云开发SDK,
废话少说,上图
二、开始教程
第一步:添加依赖
代码语言:yaml复制dependencies:
flutter:
sdk: flutter
file_picker: ^1.6.3 2
cloudbase_core: ^0.0.4
cloudbase_auth: ^0.0.5
cloudbase_function: ^0.0.2
cloudbase_storage: ^0.0.2
cloudbase_database: ^0.0.7
注意,这里的file_picker只是用来在测试云开发对象存储文件上传时选择本地文件用的,与云开发无关
配置好后记得下载安装一下依赖
代码语言:javascript复制flutter pub get
第二步:导入依赖
自己按需导入哈
代码语言:javascript复制import 'package:cloudbase_core/cloudbase_core.dart';
import 'package:cloudbase_auth/cloudbase_auth.dart';
import 'package:cloudbase_function/cloudbase_function.dart';
import 'package:cloudbase_storage/cloudbase_storage.dart';
import 'package:cloudbase_database/cloudbase_database.dart';
第三步:云开发实例
准备工作
我们先去云开发后台配置一下自己的云开发环境
这里我们新建了一个名为 addOne 的 Nodejs 云函数,来测试Flutter调用云函数实现简单加法
接着我们来到云开发数据库,新建一个名为 letters 的测试文档集,并添加一条测试数据
配置一下 letters 文档集的访问权限,方便一会我们在Flutter端匿名登陆云开发环境,正常获取到文档数据
OK,到这里云开发测试环境的准备工作就做好了。
示例程序
Life is short, show me the code.
话不多说,上代码
代码语言:javascript复制import 'dart:io';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:cloudbase_core/cloudbase_core.dart';
import 'package:cloudbase_auth/cloudbase_auth.dart';
import 'package:cloudbase_function/cloudbase_function.dart';
import 'package:cloudbase_storage/cloudbase_storage.dart';
import 'package:cloudbase_database/cloudbase_database.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter接入腾讯云开发',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter接入腾讯云开发'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
bool flag = false;
String filePath = '';
List dbDocuments = [];
CloudBaseCore core;
CloudBaseAuth auth;
CloudBaseDatabase db;
CloudBaseStorage storage;
CloudBaseFunction cloudbase;
///加号按钮点击事件
void _incrementCounter() async {
if (!flag) return;
//调用云函数 1
CloudBaseResponse res =
await cloudbase.callFunction('addOne', {'num': _counter});
setState(() {
_counter = res.data['result'];
});
}
///将本地文件上传到cos
upload() async {
File file = await FilePicker.getFile();
if (file != null) {
await storage.uploadFile(
cloudPath: file.path.split("/").last, filePath: file.path);
setState(() {
filePath = file.path.split("/").last;
});
}
}
///查询云数据库文档
getDocument() async {
db
.collection('letters')
.where({'date': '2020-04-20'}) //获取date日期为2020-04-20的文档
.get()
.then((res) {
setState(() {
dbDocuments = res.data;
});
})
.catchError((e) {
print('获取文档失败');
});
}
///初始化云开发
init() async {
// 初始化
core = CloudBaseCore.init({'env': 'xxxxx-xxxxxx'});
// 获取登录对象
auth = CloudBaseAuth(core);
// 唤起匿名登录
await auth.signInAnonymously().then((success) async {
// 登录成功
db = CloudBaseDatabase(core); //初始化数据库
storage = CloudBaseStorage(core); //初始化对象存储
cloudbase = CloudBaseFunction(core); //初始化云函数
setState(() {
flag = true;
});
print('登录成功');
}).catchError((err) {
// 登录失败
setState(() {
flag = false;
});
print('登录失败');
});
}
@override
void initState() {
super.initState();
Future.delayed(Duration.zero, () async {
await init();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: <Widget>[
Builder(
builder: (BuildContext context) {
return PopupMenuButton(
onSelected: (String value) async {
switch (value) {
case "上传":
await upload();
break;
case "查询":
await getDocument();
break;
}
},
itemBuilder: (BuildContext context) =>
<PopupMenuItem<String>>[
PopupMenuItem(value: "上传", child: Text("对象存储->上传文件")),
PopupMenuItem(value: "查询", child: Text("云数据库->查询数据")),
]);
},
)
],
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Offstage(
offstage: filePath.length < 1,
child: Text(
'文件已上传(来自对象存储)n' filePath,
)),
Text(
dbDocuments.length > 0
? '获取到${dbDocuments.length}个文档(来自云数据库)n'
dbDocuments.first['letter']
: '',
),
Text(
'你点击了$_counter次加号(来自云函数)',
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
child: Icon(Icons.add),
),
);
}
@override
void dispose() async {
super.dispose();
//退出登录
await auth?.signOut();
}
}
首先我们在当前页面加载时,初始化一下自己的云开发环境
代码语言:javascript复制 ///初始化云开发
init() async {
// 初始化
core = CloudBaseCore.init({'env': 'xxxxx-xxxxxx'});//这里要填上自己的云开发环境id
// 获取登录对象
auth = CloudBaseAuth(core);
// 唤起匿名登录
await auth.signInAnonymously().then((success) async {
// 登录成功
db = CloudBaseDatabase(core); //初始化数据库
storage = CloudBaseStorage(core); //初始化对象存储
cloudbase = CloudBaseFunction(core); //初始化云函数
setState(() {
flag = true;
});
print('登录成功');
}).catchError((err) {
// 登录失败
setState(() {
flag = false;
});
print('登录失败');
});
}
然后来看一下点击加号按钮会触发的_incrementCounter函数
代码语言:javascript复制 ///加号按钮点击事件
void _incrementCounter() async {
if (!flag) return;
//调用云函数 1
CloudBaseResponse res =
await cloudbase.callFunction('addOne', {'num': _counter});
setState(() {
_counter = res.data['result'];
});
}
这里我们是直接调用了前面设置好的云函数 addOne 来实现 _counter 的增加功能,来测试云开发调用云函数的能力
代码语言:javascript复制 ///将本地文件上传到cos
upload() async {
File file = await FilePicker.getFile();
if (file != null) {
await storage.uploadFile(
cloudPath: file.path.split("/").last, filePath: file.path);
setState(() {
filePath = file.path.split("/").last;
});
}
}
///查询云数据库文档
getDocument() async {
db
.collection('letters')
.where({'date': '2020-04-20'}) //获取date日期为2020-04-20的文档
.get()
.then((res) {
setState(() {
dbDocuments = res.data;
});
})
.catchError((e) {
print('获取文档失败');
});
}
然后再来点击程序右上角的Popmenu来测试下Flutter使用云开发上传cos文件和查询云开发数据库文档的能力
一切正常,这样就在Flutter里接入好腾讯云云开发了。
关于云开发的更多能力,可以参考官方文档(坑),地址:https://docs.cloudbase.net/api-reference/flutter/install.html
第四步:实名表(tu)扬(cao)官方文档
没错,这里我要专门用一个段落来表扬吐槽云开发的文档,
无图无真相,上图
这是腾讯云官网里面的云开发文档截图,地址 https://cloud.tencent.com/document/product/876/41616
当时是在2020年3月16号,我需要给自己的应用接入云数据库,就在找云开发Flutter SDK文档
然后看到这里只有登录鉴权、云函数和对象存储的插件,自己心里就凉了一半~
无奈,自己甚至想到云开发官方团队仓库下面准备提issue,然后想或许pub.dev里会有云数据库的第三方库
还真被我找到了,
原来云开发数据库的官方Flutter SDK是在3月13日刚刚发布的,官方文档可能还没来得及更新,
这里在找云开发数据库Flutter插件的小伙伴们要注意了哈,因为直到现在文档 https://cloud.tencent.com/document/product/876/41616 里也没有更新cloudbase_datebase插件。。。
不过你可以去云开发的的官网 https://docs.cloudbase.net/api-reference/flutter/install.html,这里的云开发文档是最新的
你以为这就完了?没有,我再举几个例子
我不是来专门找茬的哈,只是觉得把官方文档里的示例代码复制到自己的编辑器里就报错,这个体验很不爽嘛~
云开发的官方文档有很多细节的地方会有小错误,
虽然这些小细节的地方无关紧要,但是让人觉得不够严谨,不像是一份官方文档该有的样子。
还有一个地方,我搞不大明白,
为什么云开发里面的云函数环境只有Nodejs和php?
难道这里的云函数和腾讯云里单独的云函数业务环境是分离的?
我想可能这个云开发的定位之前是小程序,走的还是前端网页开发那一套,所以只用Nodejs和php环境就可以了,
但是现在云开发的使用场景已经布局到了移动端,这样的话只有js和php这两个语言环境就有点不大够用了
真的是强烈希望云开发的团队可以把云函数的运行环境支持java,pyhton,golang之类,就像独立的云函数那样
这样云开发的全端开发体验就真的无敌,真香了~
总之云开发Flutter SDK才刚刚开始发布嘛,
文档这一块可能没有仔细检查或者跟上更新进度之类,
这个大家还是要多多见谅,开发者自己多注意一下,
然后衷心祝愿腾讯云云开发能够越来越强大,越来越好,为更多开发者带来便利服务。
云开发,加油鸭!
三、文章最后
如果你有了解我之前的系列文章的话,
你应该晓得我是比较喜欢SCF COS这个组合来搞全栈应用的,
当然这种方式只是适合一些简单数据的增删查改,功能比较鸡肋。
现在我的需求是给自己的Flutter应用做一个完备的用户管理系统,
这种情况的话,使用云开发会是一个不错的选择。
所以今天我终于上了云开发的车,
因为云开发基础版套餐是有免费额度的,
哈哈哈哈,穷就一个字,我只说一次XD
逃~