HarmonyOS 鸿蒙学习笔记2-网络哀求、端云一体化

打印 上一主题 下一主题

主题 790|帖子 790|积分 2370

一、网络哀求

1、HTTP数据哀求

应用通过`HTTP`发起一个数据哀求,支持常见的`GET`、`POST`、`OPTIONS`、`HEAD`、`PUT`、`DELETE`、`TRACE`、`CONNECT`方式。
束缚与限制

利用网络管理模块的相干功能时,必要哀求相应的权限。
| 权限名 | 阐明 |
| ------ | ------ |
| ohos.permission.GET_NETWORK_INFO | 获取网络毗连信息。 |
| ohos.permission.SET_NETWORK_INFO | 修改网络毗连状态。 |
| ohos.permission.INTERNET | 允许程序打开网络套接字,进行网络毗连。 |

利用`Stage`模型的应用,在`module.json5`配置文件中声明权限:
```js
  1. {
  2.   "module" : {
  3.     // ...
  4.     "requestPermissions":[
  5.       {
  6.         "name" : "ohos.permission.INTERNET",
  7.         "reason": "描述申请权限的原因"
  8.       }
  9.     ]
  10.   }
  11. }
复制代码
```
[权限详细属性配置](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/accesstoken-guidelines-0000001493744016-V3)

http模块

`HTTP`数据哀求功能告急由`http`模块提供,涉及的接口如下表,具体的接口阐明参考[API文档](https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/js-apis-http-0000001478061929-V3)。
| 接口名 | 功能描述 |
| ------ | ------ |
| createHttp() | 创建一个http哀求。 |
| request() | 根据URL所在,发起HTTP网络哀求。 |
| destroy() | 中断哀求任务。 |
| on(type: 'headersReceive') | 订阅HTTP Response Header 事件。 |
| off(type: 'headersReceive') | 取消订阅HTTP Response Header 事件。 |
| once(type: 'headersReceive') | 订阅HTTP Response Header 事件,但是只触发一次。 |

request接口开辟步调

1. 从`@ohos.net.http`中导入`http`模块。
2. 调用`createHttp()`方法,创建一个`HttpRequest`对象。
3. 调用该对象的`on()`方法,订阅`http`响应头事件,此接口会比`request`哀求先返回。可以根据业务必要订阅此消息。
4. 调用该对象的`request()`方法,传入`http`哀求的`url`所在和可选参数,发起网络哀求。
5. 按照实际业务必要,解析返回结果。
6. 调用该对象的`off()`方法,取消订阅`http`响应头事件。
7. 当该哀求利用完毕时,调用`destroy()`方法自动烧毁。
```js
  1. // 引入包名
  2. import http from '@ohos.net.http';
  3. // 每一个httpRequest对应一个HTTP请求任务,不可复用
  4. let httpRequest = http.createHttp();
  5. // 用于订阅HTTP响应头,此接口会比request请求先返回。可以根据业务需要订阅此消息
  6. // 从API 8开始,使用on('headersReceive', Callback)替代on('headerReceive', AsyncCallback)。 8+
  7. httpRequest.on('headersReceive', (header) => {
  8.     console.info('header: ' + JSON.stringify(header));
  9. });
  10. httpRequest.request(
  11.     // 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定
  12.     "EXAMPLE_URL",
  13.     {
  14.         method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET
  15.         // 开发者根据自身业务需要添加header字段
  16.         header: {
  17.             'Content-Type': 'application/json'
  18.         },
  19.         // 当使用POST请求时此字段用于传递内容
  20.         extraData: {
  21.             "data": "data to send",
  22.         },
  23.         expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
  24.         usingCache: true, // 可选,默认为true
  25.         priority: 1, // 可选,默认为1
  26.         connectTimeout: 60000, // 可选,默认为60000ms
  27.         readTimeout: 60000, // 可选,默认为60000ms
  28.         usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
  29.     }, (err, data) => {
  30.         if (!err) {
  31.             // data.result为HTTP响应内容,可根据业务需要进行解析
  32.             console.info('Result:' + JSON.stringify(data.result));
  33.             console.info('code:' + JSON.stringify(data.responseCode));
  34.             // data.header为HTTP响应头,可根据业务需要进行解析
  35.             console.info('header:' + JSON.stringify(data.header));
  36.             console.info('cookies:' + JSON.stringify(data.cookies)); // 8+
  37.         } else {
  38.             console.info('error:' + JSON.stringify(err));
  39.             // 取消订阅HTTP响应头事件
  40.             httpRequest.off('headersReceive');
  41.             // 当该请求使用完毕时,调用destroy方法主动销毁
  42.             httpRequest.destroy();
  43.         }
  44.     }
  45. );
复制代码
```


2、应用文件的上传和下载

用户文件的上传和下载
> 在开辟过程中,避免不了要去上传下载一些文件,如上传头像、生存图片、生存音频等。

上传

起首用户必要选择文件,这里必要用到`@ohos.file.picker`模块,选择之后会得到一个`uri`本地文件所在,以图片选择为例:
```js
  1. import picker from '@ohos.file.picker';
  2. @Entry
  3. @Component
  4. struct Picker {
  5.   @State url:string=""
  6.   build() {
  7.     Row() {
  8.       Column() {
  9.         if(this.url){
  10.           Image(this.url)
  11.             .width("100%")
  12.         }
  13.         Text("选择图片")
  14.           .textAlign(TextAlign.Center)
  15.           .lineHeight(80)
  16.           .onClick(async()=>{
  17.             // 创建picker实例
  18.             let photoPicker = new picker.PhotoViewPicker();
  19.             // 通过选择模式拉起photoPicker界面,用户可以选择一个或多个图片/视频。
  20.             let result = await photoPicker.select()
  21.             // photoUris为选择的图片uri集合
  22.             this.url = result.photoUris[0]
  23.           })
  24.       }
  25.       .width('100%')
  26.     }
  27.     .height('100%')
  28.   }
  29. }
复制代码
```
执行上传利用:
```js
  1. import picker from '@ohos.file.picker';
  2. import request from '@ohos.request';
  3. import common from '@ohos.app.ability.common';
  4. import fs from '@ohos.file.fs';
  5. @Entry
  6. @Component
  7. struct Picker {
  8.   @State url:string="";
  9.   private context = getContext(this) as common.UIAbilityContext;
  10.   build() {
  11.     Row() {
  12.       Column() {
  13.         if(this.url){
  14.           Image(this.url)
  15.             .width("100%")
  16.         }
  17.         Text("选择图片")
  18.           .textAlign(TextAlign.Center)
  19.           .lineHeight(80)
  20.           .onClick(async()=>{
  21.             // 创建picker实例
  22.             let photoPicker = new picker.PhotoViewPicker();
  23.             // 通过选择模式拉起photoPicker界面,用户可以选择一个或多个图片/视频。
  24.             let result = await photoPicker.select()
  25.             // photoUris为选择的图片uri集合
  26.             this.url = result.photoUris[0];
  27.             // 将文件拷贝至cache目录,目前request.uploadFile只能上传cache目录下的文件 需要用到fs模块
  28.             let cacheDir = this.context.cacheDir;//获取缓存目录平台绝对路径
  29.             let imgName = this.url.split('/').pop()+".jpg";
  30.             let dstPath = cacheDir + '/' + imgName;//目标地址
  31.             let srcFile = fs.openSync(this.url);//选择的文件
  32.             let dstFile = fs.openSync(dstPath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);//目标文件
  33.             fs.copyFileSync(srcFile.fd, dstFile.fd);//拷贝
  34.             fs.closeSync(srcFile);//关闭文件访问
  35.             fs.closeSync(dstFile);//关闭文件访问
  36.             // 上传请求配置信息
  37.             let uploadConfig = {
  38.               url: 'http://xxx.com/upload_file', //需要手动替换为真实服务器地址
  39.               method: "POST",
  40.               // name为上传文件的参数名
  41.               files: [{ filename: imgName, name: "file", uri: 'internal://cache/' + imgName, type: "jpg" }],
  42.               header:{},
  43.               // 携带额外字段
  44.               data:[
  45.                 // { name: 'name', value: 'value' }
  46.               ]
  47.             };
  48.             try{
  49.               let uploadTask = await request.uploadFile(this.context,uploadConfig);
  50.               uploadTask.on('complete', (taskStates) => {
  51.                 // 上传完毕,不会返回响应结果,可以生成唯一标识,后端提供接口 获取上传地址
  52.                 console.info(`----upload complete taskState: ${JSON.stringify(taskStates)}`);
  53.                 // 删除拷贝的文件
  54.                 fs.unlink(dstPath)
  55.               });
  56.             }
  57.             catch(err){
  58.               console.log(JSON.stringify(err),"--------------------")
  59.             }
  60.           })
  61.       }
  62.       .width('100%')
  63.     }
  64.     .height('100%')
  65.   }
  66. }
复制代码
```
下载

```js
  1. import common from '@ohos.app.ability.common';
  2. import fs from '@ohos.file.fs';
  3. import request from '@ohos.request';
  4. // 获取应用文件路径
  5. let context = getContext(this) as common.UIAbilityContext;
  6. let filesDir = context.filesDir;
  7. request.downloadFile(context, {
  8.   url: 'http://www.mobiletrain.org/images/index/new_logo.png',//资源在线地址
  9.   filePath: filesDir + '/new_logo.png'//本地存储地址
  10. }).then((downloadTask) => {
  11.   console.log("----------------------------------")
  12.   downloadTask.on('complete', () => {
  13.     // 需要拼接"file://"前缀 才能在页面中访问
  14.     this.url = "file://"+filesDir + '/new_logo.png'
  15.     console.log("下载完毕",this.url)
  16.   })
  17. }).catch((err) => {
  18.   console.log(`下载失败, code: ${err.code}, message: ${err.message}`);
  19. });
复制代码
```
3、利用Axios

Axios

> `Axios` ,是一个基于 `promise` 的网络哀求库,可以运行 `node.js` 和浏览器中。本库基于`Axios` 原库`v1.3.4`版本进行适配,使其可以运行在 `OpenHarmony`,并相沿其现有用法和特性。

- `http` 哀求
- `Promise API`
- `request` 和 `response` 拦截器
- 转换 `request `和 `response` 的 `data` 数据
- 自动转换 `JSON data` 数据

下载安装

```
ohpm install @ohos/axios
```


接口和属性列表

| 接口 | 参数 | 功能 |
| ------ | ------ | ------ |
| axios(config) | config:哀求配置 | 发送哀求 |
| axios.create(config) | config:哀求配置 | 创建实例 |
| axios.request(config) | config:哀求配置 | 发送哀求 |
| axios.get(url[, config]) | url:哀求所在<br/>config:哀求配置 | 发送get哀求 |
| axios.delete(url[, config]) | url:哀求所在<br/>config:哀求配置 | 发送delete哀求 |
| axios.post(url[, config]) | url:哀求所在<br/>data:发送哀求体数据<br/>config:哀求配置 | 发送post哀求 |
| axios.put(config) | url:哀求所在<br/>data:发送哀求体数据<br/>config:哀求配置 | 发送put哀求 |

| 属性 | 描述 |
| ------ | ------ |
| axios.defaults['xxx'] | 默认设置值,为哀求配置 config 中的配置项</br>例如 axios.defaults.headers 获取头部信息 |
| axios.interceptors | 拦截器 |

哀求配置

上传和下载和web端的axios有些差异,其他根本同等。
```js
  1. {
  2.   // `url` 是用于请求的服务器 URL
  3.   url: '/user',
  4.   // `method` 是创建请求时使用的方法 支持post/get/put/delete方法,不区分大小写,默认为get方法
  5.   method: 'get', // default
  6.   // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
  7.   // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
  8.   baseURL: 'https://www.xxx.com/info',
  9.   // `transformRequest` 允许在向服务器发送前,修改请求数据
  10.   // 它只能用于 'PUT', 'POST' 和 'PATCH' 这几个请求方法
  11.   // 数组中最后一个函数必须返回一个字符串, 一个Buffer实例,ArrayBuffer,FormData,或 Stream
  12.   // 你可以修改请求头。
  13.   transformRequest: [function (data, headers) {
  14.     // 对发送的 data 进行任意转换处理
  15.     return data;
  16.   }],
  17.   // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
  18.   transformResponse: [function (data) {
  19.     // 对接收的 data 进行任意转换处理
  20.     return data;
  21.   }],
  22.   // `headers` 是即将被发送的自定义请求头
  23.   headers: {'Content-Type': 'application/json'},
  24.   // `params` 是即将与请求一起发送的 URL 参数
  25.   // 必须是一个无格式对象(plain object),其他对象如 URLSearchParams ,必须使用 paramsSerializer 进行序列化
  26.   params: {
  27.     ID: 12345
  28.   },
  29.   // `paramsSerializer` 是一个负责 `params` 序列化的函数
  30.   paramsSerializer: function(params) {
  31.     return params
  32.   },
  33.   // `data` 是作为请求主体被发送的数据
  34.   // 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
  35.   // 在没有设置 `transformRequest` 时,必须是以下类型之一,其他类型使用 transformRequest 转换处理
  36.   // - string, plain object, ArrayBuffer
  37.   data: {
  38.     firstName: 'Fred'
  39.   },
  40.   // 发送请求体数据的可选语法
  41.   // 请求方式 post
  42.   // 只有 value 会被发送,key 则不会
  43.   data: 'Country=Brasil&City=Belo Horizonte',
  44.   // `timeout` 指定请求超时的毫秒数(0 表示无超时时间)
  45.   // 如果请求超过 `timeout` 的时间,请求将被中断
  46.   timeout: 1000,
  47.   // `adapter` 允许自定义处理请求,这使测试更加容易。
  48.   // 返回一个 promise 并提供一个有效的响应 (参见 lib/adapters/README.md)。
  49.   adapter: function (config) {
  50.     /* ... */
  51.   },
  52.   // 如果设置了此参数,系统将使用用户指定路径的CA证书,(开发者需保证该路径下CA证书的可访问性),否则将使用系统预设CA证书,系统预设CA证书位置:/etc/ssl/certs/cacert.pem。证书路径为沙箱映射路径(开发者可通过Global.getContext().filesDir获取应用沙箱路径)。目前仅支持后缀名为.pem的文本格式证书。
  53.   caPath: '',
  54.   // 优先级,范围[1,1000],默认是1,值越大,优先级越高;
  55.   priority: 1,
  56.   //  `responseType` 指定返回数据的类型,默认无此字段。如果设置了此参数,系统将优先返回指定的类型。
  57.   // 选项包括: string:字符串类型; object:对象类型; array_buffer:二进制数组类型。
  58.   responseType: 'string',
  59.   // `onUploadProgress` 允许为上传处理进度事件,上传文件必须设置该事件
  60.   onUploadProgress: function (progressEvent) {
  61.     // 对原生进度事件的处理
  62.   },
  63.   // `onDownloadProgress` 允许为下载处理进度事件,下载文件必须设置该事件
  64.   onDownloadProgress: function (progressEvent) {
  65.     // 对原生进度事件的处理
  66.   },
  67.   // 基于应用程序的上下文,只适用于上传/下载请求
  68.   context: context,
  69.   // 下载路径。此参数,只适用于下载请求,
  70.   // Stage模型下使用AbilityContext 类获取文件路径,比如:'${getContext(this).cacheDir}/test.txt’并将文件存储在此路径下
  71.   filePath: context,
  72. }
复制代码
```
利用示例

```js
  1. import axios from '@ohos/axios'
  2. axios.get("http://xxxx").then(({data})=>{
  3.   console.log(data)
  4. })
复制代码
```
上传文件

```js
  1. import axios from '@ohos/axios'
  2. import { FormData } from '@ohos/axios'
  3. let formData = new FormData()
  4. formData.append('file', 'internal://cache/blue.jpg')
  5. // 发送请求
  6. axios.post('https://www.xxx.com/upload', formData, {
  7.   headers: { 'Content-Type': 'multipart/form-data' },
  8.   context: getContext(this),
  9.   onUploadProgress: (progressEvent) => {
  10.     console.info(progressEvent && progressEvent.loaded && progressEvent.total ? Math.ceil(progressEvent.loaded / progressEvent.total * 100) + '%' : '0%');
  11.   },
  12. }).then((res) => {
  13.   console.info("result" + JSON.stringify(res.data));
  14. }).catch((err) => {
  15.   console.error("error:" + JSON.stringify(err));
  16. })
复制代码
```
下载文件

设置下载路径`filePath`(默认在'`internal://cache/`'路径下)。

关于`filePath`:

- filePath:'workspace/test.txt':默认路径下创建workspace路径,并将文件存储在workspace路径下。
- filePath:'test.txt':将文件存储在默认路径下。
- filePath:'workspace/':默认路径下创建workspace路径,并将文件存储在workspace路径下。

```js
  1. let filePath = getContext(this).cacheDir + '/blue.jpg'
  2. // 下载。如果文件已存在,则先删除文件。
  3. try {
  4.   fs.accessSync(filePath);
  5.   fs.unlinkSync(filePath);
  6. } catch(err) {}
  7. axios({
  8.   url: 'https://www.xxx.com/blue.jpg',
  9.   method: 'get',
  10.   context: getContext(this),
  11.   filePath: filePath ,
  12.   onDownloadProgress: (progressEvent): void => {
  13.     console.info("progress: " + progressEvent && progressEvent.loaded && progressEvent.total ? Math.ceil(progressEvent.loaded / progressEvent.total * 100) : 0)
  14.   }
  15. }).then((res)=>{
  16.   console.info("result: " + JSON.stringify(res.data));
  17. }).catch((error)=>{
  18.   console.error("error:" + JSON.stringify(error));
  19. })
复制代码
```
二、端云一体化

1、端云项目搭建


> 为丰富HarmonyOS对云端开辟的支持、实现端云联动,DevEco Studio推出了云开辟功能,开辟者在创建工程时选择云开辟模板,即可在DevEco Studio内同时完成HarmonyOS应用/元服务的端侧与云侧开辟,体验端云一体化协同开辟。


相比于传统开辟模式,云开辟模式具备本钱低、效率高、门槛低等上风:

| 区别点   | 传统开辟模式                                                 | 云开辟模式                                           

| 开辟工具 | 端侧与云侧各需一套开辟工具,云侧需自建服务器,工具本钱高。  |
| DevEco Studio一套开辟工具即可支撑端侧与云侧同时开辟,无需搭建服务器,工具本钱低。 |
| 开辟人员 | 端侧与云侧要求不同的开辟语言,技能要求高。需多人投入,且开辟人员之间需连续、正确沟通,人力与沟通本钱高、效率低。 | 依托AppGallery Connect(以下简称AGC)Serverless云服务开放的接口,端侧开辟人员也能轻松开辟云侧代码,大大低落开辟门槛。开辟人员数量少,低落人力本钱,进步沟通效率。 |
| 运维     | 需自行构建运营与运维能力,本钱高、负担重。|         
| 直接接入AGC Serverless云服务,实现免运维,无运维本钱或资源浪费。 |


搭建项目


1.登录[AppGallery Connect]

(https://developer.huawei.com/consumer/cn/service/josp/agc/index.html#/) 创建应用

点击我的项目,在项目页面中添加项目


若项目中没有应用,在“项目设置”页面中添加应用


在“添加应用”页面中设置基础信息


开通必要利用的serverless服务







2.进入开辟者工具 创建端云项目


开辟者工具登录华为账号


选择云开辟基础模板


关联应用


项目结构

端云一体化开辟工程目录分为三个子工程:端开辟工程(Application)、云开辟工程(CloudProgram)、端侧公共库(External Libraries)


云开辟工程(CloudProgram)


3.部署云开辟工程


在云开辟工程目录上右键,点击Deploy Cloud Program


部署完成即可体验云开辟基础模板

2、云函数

云函数开辟


> 云函数负担传统应用后端接口的职责,在云函数内部编写业务逻辑,执行数据库访问、第三方Api调用等利用,开辟者可以在云侧工程下开辟云函数资源,包括创建函数、调试函数、部署函数。


1.创建函数


右击“cloudfunctions”目录,选择“New > Cloud Function”


输入函数名称后,点击“OK”,函数名称仅支持小写英文字母、数字、中划线(-),首字符必须为小写字母,结尾不能为中划线(-)。

2.调试函数


函数开辟过程中,可在本地进行调试,也可以将函数部署到AGC云端后,在本地触发调用云端函数。

右击“cloudfunctions”目录,选择“Run Cloud Functions”。



检察“Run”面板。如果出现“Cloud Functions loaded successfully”,表现所有函数已成功加载到本地运行的HTTP Server中,并生成对应的POST URL。



在菜单栏选择“Tools > CloudDev > Cloud Functions Requestor”,利用Cloud Functions Requestor触发函数调用。


在弹出的“Cloud Functions Requestor”面板,填写触发事件参数。


3.部署函数


完成函数代码开辟后,您可将函数部署到AGC控制台,支持单个部署和批量部署。

单个部署

右击需部署的函数量录,选择“Deploy Function”。


“底部状态栏右侧将展示函数打包与部署进度。

耐心等候,直至出现“Deploy successfully”消息,表现函数已成功部署。


登录[AppGallery Connect](https://developer.huawei.com/consumer/cn/service/josp/agc/index.html),进入当前项目的云函数服务菜单,可检察到您刚刚部署的函数,函数名称与本地工程的函数量录名相同。


批量部署指将整个云函数量录下创建的所有函数同时部署到AGC控制台。

右击“cloudfunctions”目录,选择“Deploy Cloud Functions”。


4.函数开辟


入口方法


入口方法定义如下:

```
  1. module.exports.myHandler = function(event, context, callback, logger){}
复制代码
```

- myHandler:入口方法名称。
- event:调用方传递的事件对象,JSON格式。具体内容请参见[event对象]
(https://developer.huawei.com/consumer/cn/doc/development/AppGallery-connect-Guides/agc-cloudfunction-appx-event-0000001620581529#section12463185072710)。
- context:函数运行时上下文对象,封装了日志接口、回调接口、情况变量env对象等。
- callback:事件处理惩罚结果。
- logger:记载日志。

函数必须通过表现调用callback(object)将事件处理惩罚结果返回给AGC,结果可以是恣意对象,但必须与JSON.stringify兼容,AGC会将结果转换成JSON字符串后,返回给调用方。callback执行完成,函数即执行结束。

函数调用


1. **在“项目设置”页面下载配置文件“agconnect-services.json”**



2. **将“agconnect-services.json”文件拷贝到DevEco Studio项目的恣意应用级目录下,本文直接放在“entry/src/main/ets”目录下。**

3. **添加配置文件后,必要在DevEco Studio项目中配置SDK依赖**

   - 打开DevEco Studio entry目录下的“oh-package.json5”文件,添加依赖

     ```js   
  1.  "dependencies": {
  2.        "@hw-agconnect/hmcore": "^1.0.1",
  3.        "@hw-agconnect/cloud": "^1.0.1"
  4.      }
复制代码
     ```

   - 右上方出现“Sync Now”链接,点击“Sync Now”等候同步完成。


2. **集成AGC SDK**

   - 在您的项目中导入agc组件,导入agconnect-services.json文件。

     ```js     
  1. // agconnect-services.json可放置在任意路径,本例中,agconnect-services.json放置在EntryAbility.ts的上级目录。
  2.      // @ts-ignore
  3.      import json from '../agconnect-services.json';  // DevEco import 非Ets/TS文件时会报错,可以加上@ts-ignore,不影响编译。
  4.      import { initialize } from '@hw-agconnect/hmcore';
复制代码
     ```

   - 在您的应用初始化阶段利用context初始化SDK,推荐在EntryAbility的onCreate中进行。

     ```js   
  1.  //初始化SDK
  2.      onCreate(want, launchParam) {
  3.        initialize(this.context, json);
  4.      }
复制代码
     ```

   - 在“entry/src/main/module.json5”文件中添加网络权限。

   -

     ```js   
  1.  "requestPermissions": [
  2.        {
  3.          "name": "ohos.permission.INTERNET"
  4.        }
  5.      ]
复制代码
     ```

   - **集成SDK可能会遇到的so文件优先级问题**

     在entry/build-profile.json5文件中添加配置

     ```js   
  1.  {
  2.        "buildOption": {
  3.          "napiLibFilterOption": {
  4.            "pickFirsts": [
  5.              "**/1.so"
  6.            ],
  7.            "pickLasts": [
  8.              "**/2.so"
  9.            ],
  10.            "excludes": [
  11.              "**/3.so"
  12.            ],
  13.            "enableOverride": true
  14.          },
  15.        }
  16.      }
复制代码
     ```

3. **应用集成了云函数SDK后,可以在应用内直接通过SDK API调用AGC中的云函数,云函数SDK与AGC的函数调用基于HTTPS的安全访问。**

   ````js 
  1.  //引入模块
  2.    import cloud from "@hw-agconnect/cloud";
  3.    
  4.    let callFun = async ()=>{
  5.        let functionResult = await cloud.callFunction({
  6.           name:"函数名",
  7.           params:{//参数 函数内部通过event.body获取
  8.            "param1":"val1",
  9.            "param2":"val2"
  10.           }
  11.        });
  12.        console.log(functionResult.getValue())//拿到函数响应的结果
  13.    }
复制代码
   ````
3、云数据库

云数据库开辟


> 云数据库是一款支持端云数据协同管理、可扩展的Serverless数据库产物,提供简朴易用的多平台原生SDK,应用可以通过SDK直接访问云侧数据库



1.新增和导出对象类型文件


创建新的对象类型

输入“对象类型名”为“BookInfo”后,点击“下一步”

新增如下表字段后,点击“下一步”

| 字段名称 | 类型    | 主键 | 非空 | 加密 | 默认值 |
| -------- | ------- | ---- | ---- | ---- | ------ |
| id       | Integer | ✓    | ✓    | –    | –      |
| bookName | String  | –    | –    | –    | –      |
| author   | String  | –    | –    | –    | –      |

按照如下要求设置各脚色权限后,点击“下一步”

| 脚色       | query | upsert | delete |
| ---------- | ----- | ------ | ------ |
| 所有人     | ✓     | ✓      | ✓      |
| 认证用户   | ✓     | ✓      | ✓      |
| 数据创建者 | ✓     | ✓      | ✓      |
| 管理员     | ✓     | ✓      | ✓      |

点击“确定”。创建完成后返回对象类型列表,可以检察已创建的对象类型。

勾选创建的BookInfo对象类型,点击“导出”。若不勾选对象类型,默认导出所有对象类型


导出“json格式”和“js格式”文件,导出的文件在后续步调用于添加至本地开辟情况


新增存储区


2.在项目中利用


集成SDK,和云函数的用到的SDK同等

**加载对象类型文件**

将下载的两个文件放入ets/db/book/目录下

引入并利用

```js
  1. // 注意目录,目录可以自定义
  2. import { BookInfo } from './BookInfo';
  3. import schema from './Bookinfo.json';
  4. //QuickStartDemo存储区名称
  5. async function upsert () {
  6.     const record = await cloud.database({objectTypeInfo: schema, zoneName: "QuickStartDemo"})
  7.     .collection(BookInfo)
  8.     .upsert({
  9.         "id":2000,
  10.         "bookName" : "book_name",
  11.         "author" : "huawei"
  12.      });
  13. }
复制代码
```

查询数据

```js
  1. const resultArray = await cloud.database({objectTypeInfo: schema, zoneName: "QuickStartDemo"})
  2. .collection(BookInfo)
  3. .query()
  4. .get();
复制代码
```

[更多数据库利用]
(https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-Guides/agc-clouddb-otheroperations-harmonyosts-0000001626432634)
4、认证服务

认证服务


> 认证服务可以为应用快速构建安全可靠的用户认证系统,开辟者只需在应用中访问认证服务的相干能力,而不必要关心云侧的设施和实现。



开辟步调



1.申请手机注册的验证码


```js
  1. import cloud from '@hw-agconnect/cloud';
  2. import { Auth, VerifyCodeAction } from '@hw-agconnect/cloud';
  3. cloud.auth().requestVerifyCode({
  4.     action: VerifyCodeAction.REGISTER_LOGIN,
  5.     lang: 'zh_CN',
  6.     sendInterval: 60,
  7.     verifyCodeType: {
  8.         phoneNumber: '138********',
  9.         countryCode: '86',
  10.         kind: "phone"
  11.     }
  12. }).then(verifyCodeResult => {
  13.     //验证码申请成功
  14. }).catch(error => {
  15.     //验证码申请失败
  16. });
复制代码
```

2.利用手机号码注册用户


调用[Auth.createUser](https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-References/harmonyos-arkts-auth-0000001680370685#section19861514132515)注册用户。注册成功后,系统会自动登录,无需再次调用登录接口。

```js
  1. cloud.auth().createUser({
  2.     kind: 'phone',
  3.     countryCode: '86',
  4.     phoneNumber: '138********',
  5.     password: 'your password',//可以给用户设置初始密码,后续可以用密码来登录
  6.     verifyCode: 'xxxx'
  7. }).then(result => {
  8.     // 创建用户成功
  9. }).catch(error => {
  10.     // 创建用户失败
  11. })
复制代码
```

3.登录


```js
  1. cloud.auth().signIn({
  2.     credentialInfo: {
  3.         kind: 'phone',
  4.         phoneNumber: '138********',
  5.         countryCode: '86',
  6.         password: 'your password'
  7.     }
  8. }).then(user => {
  9.     //登录成功
  10. }).catch(error => {
  11.     //登录失败
  12. });
复制代码
```

4.在应用的登录界面

初始化[Auth](https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-References/harmonyos-arkts-auth-0000001680370685)实例,获取AGC的用户信息,检查是否有已经登录的用户。

如果有,则可以直接进入用户界面,否则表现登录界面。

```js
  1. cloud.auth().getCurrentUser().then(user=>{
  2.     if(user){
  3.         //业务逻辑
  4.        
  5.     }
  6. });
复制代码
```

| 类型   | 方法名及描述                                                 |
| :----- | :----------------------------------------------------------- |
| string | [getUid](https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-References/harmonyos-arkts-authuser-0000001680210801#section1312317535214)()获取用户ID,此ID由AGConnect生成。 |
| string | [getEmail](https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-References/harmonyos-arkts-authuser-0000001680210801#section1320432912212)()获取用户邮箱。 |
| string | [getPhone](https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-References/harmonyos-arkts-authuser-0000001680210801#section1169817018235)()获取用户手机号码。 |
| string | [getDisplayName](https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-References/harmonyos-arkts-authuser-0000001680210801#section948316131197)()获取用户名称。 |
| string | [getPhotoUrl](https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-References/harmonyos-arkts-authuser-0000001680210801#section1063155522017)()获取用户头像。 |
| string | [getProviderId](https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-References/harmonyos-arkts-authuser-0000001680210801#section1324190192617)()获取当前用户的提供者,第三方认证平台的名称。 |

5.设置用户头像及昵称


```js
  1. cloud.auth().getCurrentUser().then(user => {
  2.   user.updateProfile({
  3.     photoUrl: "https://xxx.png",
  4.     displayName: "HamonyOSUser"
  5.   })
  6. })
复制代码
```

6.退出登录


```js
  1. cloud.auth().signOut().then(() => {
  2.     //登出成功
  3. }).catch(error => {
  4.     //登出失败
  5. });
复制代码
```

| 错误码                                | 错误码值  | 阐明                                                         |
| ------------------------------------- | --------- | ------------------------------------------------------------ |
| NULL_TOKEN                            | 1210001   | Token为空,建议重新登录。                                 |
| NOT_SIGN_IN                           | 1210002   | 当前无已登任命户。                                           |
| USER_LINK_FAILED                      | 1210003   | 用户关联失败。                                               |
| USER_UNLINK_FAILED                    | 1210004   | 用户取消关联失败。                                       |
| ALREADY_SIGN_IN_USER                  | 1210005   | 已经利用一个帐号登录,在未登出情况下利用此帐号或者其他帐号登录。 |
| FAIL_TO_GET_ACCESS_TOKEN              | 1210006   | 获取Access Token失败。                                       |
| FAIL_TO_UPDATE_PROFILE                | 1210007   | 更新用户信息失败。                                           |
| FAIL_TO_UPDATE_EMAIL                  | 1210008   | 更新用户邮箱失败。                                           |
| CREDENTIAL_INVALID                    | 1210009   | 凭证信息不合法。                                             |
| INLVLID_EMAIL                         | 203817223 | 输入的邮箱所在不合法。                                       
| INLVLID_PHONE                         | 203817224 | 输入的手机号码不合法。                                    |
| GET_UID_ERROR                         | 203817728 | 获取用户ID失败。                                   |
| UID_PRODUCTID_NOT_MATCH               | 203817729 | 用户ID和项目ID不匹配。                                       |
| GET_USER_INFO_ERROR                   | 203817730 | 获取用户信息失败。                                           |
| AUTH_METHOD_NOT_SUPPORT               | 203817732 | 当前认证微服务部署了4个局点,每个局点支持的认证方式不同。    |
| PRODUCT_STATUS_ERROR                  | 203817744 | 项目没有开通认证服务。                                       |
| PASSWORD_VERIFICATION_CODE_OVER_LIMIT | 203817811 | 暗码验证码次数超过限制。                                     |
| INVALID_TOKEN                         | 203817984 | Client Token不可用。                                         |
| INVALID_ACCESS_TOKEN                  | 203817985 | Access Token不可用。                                         |
| INVALID_REFRESH_TOKEN                 | 203817986 | Refresh Token不可用。用户的Refresh Token过期,重新登录,获取新的Refresh Token。 |
| TOKEN_AND_PRODUCTID_NOT_MATCH         | 203817987 | Token和Product Id不匹配,建议检查“agconnect-services.json”是否与平台上申请的信息同等。 |
| AUTH_METHOD_IS_DISABLED               | 203817988 | 不支持的认证方式。                                           |
| ACCESS_TOKEN_OVER_LIMIT               | 203817991 | AccessToken数量超过了限定命量,配额是每个项目每个用户每小时500个。 |
| FAIL_TO_USER_LINK                     | 203817992 | 关联用户失败。                                               |
| FAIL_TO_USER_UNLINK                   | 203817993 | 取消用户关联失败。                                           |
| ANONYMOUS_SIGNIN_OVER_LIMIT           | 203818019 | 同一IP下的匿名用户登录超过限制,配额是每小时100个哀求。      |
| INVALID_APPID                         | 203818020 | AppID不可用。                                                |
| INVALID_APPSECRET                     | 203818021 | App Secret不可用。                                           |
| PASSWORD_VERIFY_CODE_ERROR            | 203818032 | 暗码和验证码错误。                                           |
| SIGNIN_USER_STATUS_ERROR              | 203818036 | 用户被开辟者停用。                                           |
| SIGNIN_USER_PASSWORD_ERROR            | 203818037 | 用户暗码错误。                                               |
| PROVIDER_USER_HAVE_BEEN_LINKED        | 203818038 | 身份验证提供方已经被其他用户绑定。                           |
| PROVIDER_HAVE_LINKED_ONE_USER         | 203818039 | 帐号中该身份验证提供方类型已经被绑定过。                     |
| FAIL_GET_PROVIDER_USER                | 203818040 | 获取身份验证提供方用户失败。                                 |
| CANNOT_UNLINK_ONE_PROVIDER_USER       | 203818041 | 不能对单一的身份验证提供方做取消关联利用。                   |
| VERIFY_CODE_INTERVAL_LIMIT            | 203818048 | 在发送隔断内发送验证码。                                     |
| VERIFY_CODE_EMPTY                     | 203818049 | 验证码为空。                                                 |
| VERIFY_CODE_LANGUAGE_EMPTY            | 203818050 | 验证码发送语言为空。                                         |
| VERIFY_CODE_RECEIVER_EMPTY            | 203818051 | 验证码接收器为空。                                           |
| VERIFY_CODE_ACTION_ERROR              | 203818052 | 验证码类型为空。                                             |
| VERIFY_CODE_TIME_LIMIT                | 203818053 | 验证码发送次数超过限制。                                     |
| ACCOUNT_PASSWORD_SAME                 | 203818064 | 用户名暗码同等。                                             |
| PASSWORD_STRENGTH_LOW                 | 203818065 | 暗码强度太低。                                               |
| UPDATE_PASSWORD_ERROR                 | 203818066 | 更新暗码失败。                                               |
| PASSWORD_SAME_AS_BEFORE               | 203818067 | 暗码与老暗码相同。                                           |
| PASSWORD_IS_EMPTY                     | 203818068 | 暗码为空。                                                   |
| PASSWORD_TOO_LONG                     | 203818071 | 暗码太长。                                                   |
| SENSITIVE_OPERATION_TIMEOUT           | 203818081 | 敏感利用的最近登录时间超时。                                 |
| ACCOUNT_HAVE_BEEN_REGISTERED          | 203818082 | 帐号已经被注册。                                             |
| UPDATE_ACCOUNT_ERROR                  | 203818084 | 更新帐号失败。                                               |
| USER_NOT_REGISTERED                   | 203818087 | 用户没有注册。                                               |
| VERIFY_CODE_ERROR                     | 203818129 | 验证码错误。                                                 |
| USER_HAVE_BEEN_REGISTERED             | 203818130 | 用户已经被注册。                                             |
| REGISTER_ACCOUNT_IS_EMPTY             | 203818132 | 注册帐号为空。                                               |
| VERIFY_CODE_FORMAT_ERROR              | 203818134 | 验证码格式错误。                                             |
| VERIFY_CODE_AND_PASSWORD_BOTH_NULL    | 203818135 | 验证码和暗码都为空。                                         |
| SEND_EMAIL_FAIL                       | 203818240 | 发送邮件失败。                                               |
| SEND_MESSAGE_FAIL                     | 203818241 | 发送短信失败。                                               |
| CONFIG_LOCK_TIME_ERROR                | 203818261 | 暗码/验证码最大尝试次数超过设定值后对帐号进行冻结处理惩罚,冻结期间用户无法利用该帐号进行暗码验证/验证码验证。 |


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

温锦文欧普厨电及净水器总代理

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表