【玩转腾讯云】万物皆可Serverless之在Flutter中快速接入腾讯云开发

2020-04-22 18:13:06 浏览数 (2)

万物皆可Serverless系列文章

  1. 万物皆可Serverless之免费搭建自己的不限速大容量云盘(5TB)
  2. 万物皆可Serverless之使用云函数Timer触发器实现每天自动定时打卡
  3. 万物皆可Serverless之使用SCF COS快速开发全栈应用
  4. 万物皆可Serverless之使用SCF COS免费运营微信公众号
  5. 万物皆可Serverless之使用SCF快速部署验证码识别接口
  6. 万物皆可Serverless之Kaggle SCF端到端验证码识别从训练到部署
  7. 万物皆可Serverless之借助微信公众号简单管理用户激活码
  8. 万物皆可Serverless之使用SCF COS给未来写封信
  9. 万物皆可Serverless之在Flutter中快速接入腾讯云开发
  10. 万物皆可Serverless之在Flutter中写一个Dart原生腾讯云对象存储插件
  11. 万物皆可Serverless之我的Serverless之路

一、本文介绍

云开发(Tencent Cloud Base,TCB)是腾讯云为移动开发者提供的高可用、自动弹性扩缩的后端云服务,包含计算、存储、CDN、静态托管等能力(Serverless 化),可用于开发多种端应用(小程序,公众号,Web 应用,Flutter 客户端等,后续会陆续支持 iOS 和 Android 等移动应用开发),达到一站式后台服务构建多端应用,帮助开发者统一构建和管理后端服务和后端云资源,避免了应用开发过程中参与繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。

这是腾讯云官方文档的里的关于云开发的简介,

本文将带领大家按照云开发的官方文档在Flutter中快速接入一下腾讯云开发SDK,

废话少说,上图

Flutter接入云开发demoFlutter接入云开发demo

二、开始教程

第一步:添加依赖

代码语言: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准备提issue

无奈,自己甚至想到云开发官方团队仓库下面准备提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运行环境

还有一个地方,我搞不大明白,

为什么云开发里面的云函数环境只有Nodejs和php?

难道这里的云函数和腾讯云里单独的云函数业务环境是分离的?

我想可能这个云开发的定位之前是小程序,走的还是前端网页开发那一套,所以只用Nodejs和php环境就可以了,

但是现在云开发的使用场景已经布局到了移动端,这样的话只有js和php这两个语言环境就有点不大够用了

真的是强烈希望云开发的团队可以把云函数的运行环境支持java,pyhton,golang之类,就像独立的云函数那样

这样云开发的全端开发体验就真的无敌,真香了~

独立的云函数运行环境支持nodejs、php、python、java和golang独立的云函数运行环境支持nodejs、php、python、java和golang

总之云开发Flutter SDK才刚刚开始发布嘛,

文档这一块可能没有仔细检查或者跟上更新进度之类,

这个大家还是要多多见谅,开发者自己多注意一下,

然后衷心祝愿腾讯云云开发能够越来越强大,越来越好,为更多开发者带来便利服务。

云开发,加油鸭!

三、文章最后

如果你有了解我之前的系列文章的话,

你应该晓得我是比较喜欢SCF COS这个组合来搞全栈应用的,

当然这种方式只是适合一些简单数据的增删查改,功能比较鸡肋。

现在我的需求是给自己的Flutter应用做一个完备的用户管理系统,

这种情况的话,使用云开发会是一个不错的选择。

所以今天我终于上了云开发的车,

因为云开发基础版套餐是有免费额度的,

哈哈哈哈,穷就一个字,我只说一次XD

逃~

0 人点赞