Skip to content

证书、打包与实人认证(二) ​

本页对应 证书、打包与实人认证,共 6 段视频,约 56 分钟。

学习目标 ​

  • 能说明地图服务与消息推送配置中云端证书的作用,并能从云端证书中准确提取 SHA1、MD5、SHA256 用于后续平台配置。
  • 能核对 AppID,完成 Android/iOS 平台应用信息添加,正确填写包名、SHA1、MD5、SHA256,并保证与云打包配置一致。
  • 能按文档在华为开发者平台完成项目创建、应用添加、推送服务开通、证书添加和应用回执配置,并将 AppID、Secret、包名及 agconnect-services.json 正确回填到 UniPush 厂商推送设置。
  • 能在 HBuilderX 的 manifest 模块设置中勾选 Push 2.0 与离线推送,区分自定义调试基座和云打包正式包,并完成云打包后安装验证消息推送。
  • 能完成一键登录服务开通、充值、应用添加及审核状态判断,并在 manifest 中勾选“一键登录”模块。
  • 能使用 uni.login 调起一键登录授权界面,通过条件编译限制仅 APP 端触发,并按文档定制 logo、按钮颜色和隐私勾选图标等样式。

知识点 ​

本节范围说明 ​

本节笔记主题是“1.3 地图服务”,核心是跨端地图服务商兼容性、平台选型,以及在高德开放平台创建应用 Key 时需要的 PackageName 和 SHA1。转写稿后半段主要讲消息推送、一键登录,和地图服务不是同一节内容;下面只采用转写稿开头与“证书、包名、SHA1”相关的部分,不把消息推送、一键登录的步骤混进地图服务。转写稿里的“傻一”应纠正为 SHA1,“傻256”是 SHA256,“报名”应理解为“包名”。

为什么先看地图服务兼容性 ​

为什么需要:uni-app 一套代码跑 App、H5、小程序,但地图服务商并不是所有平台都完全支持。如果不先看兼容性,可能在 H5 调通了,打包到 App 或小程序才发现服务商不支持。

怎么想:先按运行平台选服务商,再谈创建 Key。笔记给出的兼容性如下:

地图服务商AppH5小程序
高德√√
Google仅nvue页面√
腾讯√√

怎么做:H5 和小程序平台选择腾讯地图服务平台;App 选择高德地图服务平台,并自行注册高德地图开发者账号、创建应用。

易错点:不要把 H5 的腾讯 Key 直接拿去给 App 高德用;Google 在 App 端“仅 nvue 页面”可用,普通 vue 页面不能想当然认为可用;表格空白处表示该平台不要按这个服务商去配。

平台选型:H5/小程序用腾讯,App 用高德 ​

为什么需要:地图 Key 通常和平台、包名、签名绑定,选型不清就会重复建应用、反复改配置。

怎么想:把“平台”和“服务商”一一对应:H5、小程序走腾讯地图;App 走高德地图。Google 只作为兼容性表里的特殊情况看待。

怎么做:先分别到腾讯地图和高德开放平台注册开发者账号;按笔记要求在高德侧创建应用。创建应用 Key 时,笔记特别提示要关注 PackageName 和 SHA1。

易错点:不要等代码写完才补 Key;不要一个平台配多个服务商后混用 Key;App 端选高德后,打包配置里的包名要与高德后台一致。

创建高德应用 Key:PackageName 与 SHA1 ​

为什么需要:地图 SDK/API 需要 Key 做鉴权,而 PackageName、SHA1 是 Android 应用身份的重要信息。Key 绑定这些信息后,才能降低被其他应用盗用的风险。

怎么想:先确定包名,再获取签名。笔记明确说:PackageName 是在自定义调试基座和正式包时定义的包名;SHA1 的获取方式如下所示。

怎么做:在高德开放平台创建应用时填写 PackageName;SHA1 从证书信息中获取。原笔记此处代码块为空:

bash

转写稿也没有给出具体命令,只说明证书可以通过本地打包或 HBuilderX/DCloud 云端证书获得,最终要拿到 SHA1、MD5、SHA256 等关键信息。因此这里不补造命令,实际以证书详情页显示为准:查看云端证书详情,复制 SHA1 到高德后台对应位置。

易错点:包名一旦确定不要随便改;转写稿里提到“一会儿 test、一会儿 demo,自己都晕了”,就是包名反复变导致配置混乱。打包时填写的包名必须和高德后台 PackageName 一模一样;SHA1 复制时一个字母都不能少;不要拿调试临时包名的签名去配正式包。

从转写稿补:证书、包名与 SHA1 的调试线索 ​

为什么需要:地图 Key 配不对,常见原因不是代码,而是包名或签名不一致。

怎么想:转写稿开头说,讲地图使用时需要证书打包,证书有本地打包和云端证书两种,最终都要获得 SHA1、MD5、SHA256 等关键信息。所以调试顺序应是:先定包名 → 再取证书里的 SHA1 → 填到高德后台 → 打包验证。

怎么做:如果使用云端证书,就查看证书详情,单独复制 SHA1 备用;如果使用自有证书,就保证打包所用证书与后台填写一致。转写稿强调“包名确定好一个,不要乱改”,这条同样适用于地图服务。

易错点:不要把 MD5、SHA1、SHA256 混填;不要只改打包配置不改高德后台;不要用未对应包名的 Key 去调试 App。

本节易错点清单 ​

  • H5/小程序选腾讯,App 选高德;Google 在 App 仅 nvue 页面可用。
  • PackageName 是自定义调试基座和正式包时定义的包名,后台与打包处必须一致。
  • SHA1 从证书信息中获取,转写稿中的“傻一”就是 SHA1。
  • 原笔记 SHA1 代码块为空,转写稿未给具体命令,不编造命令。
  • 包名不要反复改;改包名后要同步高德后台并重新打包验证。

2.1 消息推送概述 ​

消息推送是服务端管理后台主动向安装了 App 的用户发送消息的功能。本节把它分成两类理解:离线推送和在线推送。离线推送本质上是厂商推送设置,优势是不需要在 App 中额外添加代码、不引入 SDK 就能实现推送;代价是要针对不同品牌手机分别配置参数。转写稿中演示时,后台发出“测试推送”后手机并不是立刻收到,而是稍等了一下才出现通知,这说明推送链路存在一定延时,测试时不要刚点完就判断失败。

为什么需要先理解这个分类?因为后续配置不是“只配一个总开关”,而是要把应用信息、厂商通道、uniPush 后台和打包环节串起来。怎么想?先确认当前操作的是哪个 App,再补平台信息,最后配置厂商通道并重新打包。易错点是:把在线推送和离线推送混为一谈,或者以为后台点一下发送就一定能马上到达。

2.1.1 应用信息 ​

为什么需要完善应用信息?因为推送平台要识别你的 App,签名、包名等信息对不上,后续厂商通道就无法正确关联。怎么想?先在 uni-app 后台找到对应应用,核对 AppID,避免在多个应用中选错;再补安卓和 iOS 的平台信息。怎么做?按笔记填写 MD5、SHA1、SHA256 信息,这些值可从云端证书详情中获取;iOS 平台只需要填写包名。

应用平台信息填写页面

安卓签名信息填写页面

iOS平台包名填写页面

然后找到 uniPush,选择 2.0 版本,它支持全端推送。

uniPush 2.0选择页面

易错点:转写稿反复强调“包名一旦确定不要随便改”,因为打包时填写的包名必须和后台配置一模一样;复制 SHA1、SHA256 时不要多复制标题或漏字符。另一个易错点是应用选错:如果账号下有多个应用,必须按 AppID 确认当前要给“神领物流”配置,而不是给别的测试应用配置。

2.1.2 离线推送 ​

为什么需要厂商推送?因为用户手机品牌不同,App 被系统管理后,单纯依赖应用内连接不一定能稳定送达;厂商通道就是按品牌分别接入。怎么想?华为、小米、OPPO、vivo、魅族等品牌要分别配置,本节以华为为例演示,其他品牌按同样思路处理。怎么做?先注册华为开发者账号并完成身份认证,华为手机用户可直接用华为账号登录;再参考个推文档进行厂商配置。笔记给出的入口是华为开发者账号和个推服务平台文档:

易错点:不要以为在华为后台创建项目就结束了,还要让 uniPush 与华为建立关联;华为后台里“项目”和“应用”是两个概念,创建项目后还要添加应用,包名必须与 App 中一致。

2.1.3 配置神领物流 ​

为什么要在 uniPush 后台继续配置?因为厂商后台和 uniPush 是两套系统,华为后台配置完并不等于 uniPush 已经认识华为通道。怎么想?把华为侧拿到的 AppID、Secret、包名以及 agconnect-services.json 内容填到 uniPush 的厂商推送设置中。怎么做?在 uniPush 后台选择神领物流对应应用,核对包名、应用签名,关联服务空间并保存;进入厂商推送设置,选择华为,填写 AppID 和 Secret,包名保持一致,把下载文件中的内容完整粘贴到配置处,保存成功。

神领物流厂商推送配置页面

配置完成后必须重新打包。转写稿中明确区分:开发测试阶段用“运行”制作自定义调试基座;功能完成准备上线时用“发行”云打包正式包。打包前还要在 manifest.json 的模块设置中勾选 Push 2.0,并选择离线推送中的华为。易错点:配置后不重新打包就直接测试;包名前后不一致;Secret 复制不完整;agconnect-services.json 内容没有清空旧内容就粘贴,导致保存失败。

2.1.4 发送消息 ​

为什么还要回到后台发送?因为配置是否成功,最终要用真机收到通知来验证。怎么想?在 uniPush 的消息推送页面填写标题和内容,确认当前在线人数,再点确定发送。怎么做?笔记演示了填写“测试推送”和内容后发送,手机稍后收到通知。没有安卓机的同学可用 WeTest 云手机测试,注意选择华为品牌手机:https://wetest.qq.com/products/cloud-phone 。

消息推送发送页面

易错点:测试时只看后台“创建成功”不够,要观察真机通知栏;刚发送没收到时先等待并检查网络、通知权限、包名和厂商配置,不要立刻重复改配置。若使用云手机,品牌选错会导致验证不到对应厂商通道。

一键登录的定位与整体流程 ​

为什么需要:普通手机号登录要用户输入号码、收验证码,步骤多;一键登录通过运营商(移动、电信、联通)识别本机号码,授权后即可拿到手机号,适合 App 端快速登录/注册。
怎么想:客户端只负责唤起授权并拿到临时凭证;真正换取手机号必须由服务端或云函数调用运营商接口,不能把密钥放前端。
怎么做:整体链路是:开通一键登录服务 → 配置神领物流并重新打包 → 客户端 uni.login 唤起授权 → 云函数用 uniCloud.getPhoneNumber 换手机号 → 后端入库/登录。
易错点:一键登录仅适用于 App 端,网页和小程序不能用,因此登录页要做条件编译;转写稿中演示改代码后未生效,需要重新运行/编译,不要误判为 API 无效。

开通服务与后台准备 ​

为什么需要:一键登录依赖运营商能力,必须先开通服务并拿到 apiKey、apiSecret 等关键信息,云函数换手机号时要用。
怎么想:先按官方文档开通,再充值;转写稿提到该能力按次付费,需充值后才能实际获取号码。开发阶段还要注意“添加应用”的审核时间。
怎么做:参见官方文档。登录后台开通一键登录、同意协议、充值,并按 DCloud appid 和包名添加应用;审核未通过时可先用标准基座调试,审核通过后再用自定义基座。
易错点:添加应用时要选对当前项目的 DCloud appid,包名要与打包时一致;审核需要等待,不要以为保存后立刻可用。

配置神领物流并重新打包 ​

为什么需要:一键登录是 App 模块能力,打包前必须勾选对应模块,否则运行时会缺少授权能力。
怎么想:在 manifest.json 的 App 模块设置中找到“登录授权/一键登录”并勾选;开发阶段推荐自定义基座,正式上线打正式包。
怎么做:配置好后重新打包,自定义基座和正式包均可,开发阶段推荐使用自定义基座。转写稿中强调:勾选后要重新打包,再安装到手机测试。
配置神领物流
易错点:只改代码不重新打包,模块不会生效;包名前后必须统一,避免和后台添加应用、云打包配置不一致。

客户端调用:uni.login 与条件编译 ​

为什么需要:客户端需要唤起运营商授权界面,让用户确认本机号码。
怎么想:App 端调用 uni.login,provider: 'univerify' 表示一键登录;非 App 端仍走原来的切换登录逻辑。
怎么做:基础调用如下:

javascript
uni.login({
  provider: 'univerify',
  univerifyStyle: {
    fullScreen: true,
  },
})

整合到登录页时用条件编译:

vue
<!-- pages/login/index.vue -->
<script setup>
  import { ref, reactive, computed } from 'vue'
	
  // 省略中间部分代码...

  // 切换登录类型
  function changeLoginType() {
    // #ifdef APP-PLUS
    uni.login({
      provider: 'univerify',
      univerifyStyle: {
        fullScreen: true,
      },
    })
    // #endif

    // #ifndef APP-PLUS
    tabIndex.value = Math.abs(tabIndex.value - 1)
    // #endif
  }
</script>

易错点:笔记中“调用 wx.login”应为 uni.login 的笔误;非 App 端不要调用一键登录;provider 固定写 univerify。

自定义授权界面样式 ​

为什么需要:默认授权页是通用样式,需要换成神领物流的 logo、按钮色和隐私协议勾选图标,保持品牌一致。
怎么想:通过 univerifyStyle 有限定制,常用项包括 logo、按钮正常/按下颜色、隐私条款文字颜色和选中/未选中图片。
怎么做:

javascript
const { authResult } = await uni.login({
  provider: 'univerify',
  univerifyStyle: {
    fullScreen: true,
    icon: {
      path: 'static/logo.png', // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo
    },
    authButton: {
      normalColor: '#ef4f3f', // 授权按钮正常状态背景颜色 默认值:#3479f5
      highlightColor: '#ef4f3f', // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)
    },
    privacyTerms: {
      defaultCheckBoxState: false,
      uncheckedImage: 'static/images/uncheckedImage.png',
      checkedImage: 'static/images/checkedImage.png',
      termsColor: '#ef4f3f',
    },
  },
})

易错点:logo 仅支持本地图片;图片路径要放在项目静态目录并能被打包;改样式后若手机未刷新,重新运行/编译再验证。

云函数换取手机号 ​

为什么需要:客户端授权只拿到授权结果,并未真正拿到手机号;换号必须服务端或云函数调用运营商接口。
怎么想:把 apiKey、apiSecret 放在云函数,客户端只传 access_token、openid,云函数返回业务结果,不把完整手机号直接返回前端。
怎么做:先开通 uniCloud 服务空间,创建云函数。默认代码:

javascript
'use strict';
exports.main = async (event, context) => {
	//event为客户端上传的参数
	console.log('event : ', event)
	
	//返回数据给客户端
	return event
}

创建云函数
创建云函数
客户端调用:

javascript
uniCloud.callFunction({
  name: '云函数名(即文件名)',
  data: {/* 给云函数传的实参 */},
  success: (result) => {
    // result 是云函数 return 的返回值
  }
})

云函数中获取手机号:

javascript
// 在云函数中获取
'use strict'
exports.main = async (event, context) => {
  // event里包含着客户端提交的参数
  const res = await uniCloud.getPhoneNumber({
    appid: context.APPID, // 替换成自己开通一键登录的应用的DCloud appid
    provider: 'univerify',
    apiKey: 'fc7aa3fb2672f947a501f2392a22501a', // 在开发者中心开通服务并获取apiKey
    apiSecret: 'b4d9fafeb3c3ed12ff6cc97b9f9a1817', // 在开发者中心开通服务并获取apiSecret
    access_token: event.access_token,
    openid: event.openid,
  })

  console.log(res) // res里包含手机号
  // 执行用户信息入库等操作,正常情况下不要把完整手机号返回给前端
  // 在云函数中也可以调用后端接口将手机号存入后端数据中或云数据库中
  return {
    code: 200,
    message: '获取手机号成功',
  }
}

云函数依赖
易错点:云函数 package.json 要添加依赖 uni-cloud-verify;该能力需充值付费;App 端调试云函数要求手机与电脑在同一网络下,调试前需安装 HBuilderX 插件并开启断点调试。
云函数调试
获取手机号成功

代码示例 ​

示例 1:登录页 —— App 端一键登录 + 条件编译(pages/login/index.vue) ​

vue
<!-- pages/login/index.vue -->
<script setup>
import { ref } from 'vue'

// 登录方式切换索引
const tabIndex = ref(0)

// 切换登录类型
async function changeLoginType() {
  // #ifdef APP-PLUS
  // 仅 App 端才有一键登录能力
  try {
    const { authResult } = await uni.login({
      provider: 'univerify',
      univerifyStyle: {
        fullScreen: true,
        icon: {
          path: 'static/logo.png', // 自定义授权框中的 logo,仅支持本地图片,默认显示 App logo
        },
        authButton: {
          normalColor: '#ef4f3f', // 授权按钮正常状态背景色,默认 #3479f5
          highlightColor: '#ef4f3f', // 授权按钮按下状态背景色,默认 #2861c5(仅 iOS 支持)
        },
        privacyTerms: {
          defaultCheckBoxState: false,
          uncheckedImage: 'static/images/uncheckedImage.png',
          checkedImage: 'static/images/checkedImage.png',
          termsColor: '#ef4f3f',
        },
      },
    })

    // authResult 里是 access_token、openid,并不能直接拿到手机号
    await getPhoneNumber(authResult)
  } catch (err) {
    // 用户取消授权或环境不支持时进入这里
    console.log('一键登录失败/取消:', err)
  }
  // #endif

  // #ifndef APP-PLUS
  // H5、小程序没有一键登录,保持原来的 tab 切换逻辑
  tabIndex.value = Math.abs(tabIndex.value - 1)
  // #endif
}

// 把授权结果交给云函数换取手机号
function getPhoneNumber(authResult) {
  return uniCloud.callFunction({
    name: 'get-phone-number', // 云函数名,即云函数目录/文件名
    data: {
      access_token: authResult.access_token,
      openid: authResult.openid,
    },
    success: (result) => {
      // result 是云函数 return 的返回值
      console.log('云函数返回:', result.result)
    },
    fail: (err) => {
      console.log('调用云函数失败:', err)
    },
  })
}
</script>

<template>
  <view class="login-page">
    <view class="tab-bar">
      <view class="tab-item" @click="changeLoginType">手机号登录</view>
    </view>
  </view>
</template>

<style scoped>
.login-page {
  padding: 40rpx;
}
.tab-bar {
  display: flex;
  justify-content: center;
}
.tab-item {
  padding: 20rpx 40rpx;
  color: #ef4f3f;
  border: 1rpx solid #ef4f3f;
  border-radius: 40rpx;
}
</style>

关键行与易错点

  • provider: 'univerify' 是固定值,表示运营商一键登录,写错就唤不起授权弹层。
  • 一键登录只能在 App 端使用,所以必须用 #ifdef APP-PLUS / #ifndef APP-PLUS 条件编译把两端逻辑分开,否则 H5 和小程序会报错或行为异常。
  • univerifyStyle 里的 icon.path、uncheckedImage、checkedImage 仅支持本地图片,不能用网络地址。
  • uni.login 返回的是 authResult(含 access_token、openid),不是手机号,手机号必须由云函数或服务端换取。
  • 修改了 manifest 模块配置(如新增一键登录)后必须重新打包自定义基座,只重新编译运行不会生效。
  • 云函数在 App 端断点调试时,要求手机和电脑处于同一局域网。

示例 2:云函数获取手机号(index.js + package.json) ​

js
// uniCloud-aliyun/cloudfunctions/get-phone-number/index.js
'use strict'

exports.main = async (event, context) => {
  // event 里包含着客户端提交的参数
  const res = await uniCloud.getPhoneNumber({
    appid: context.APPID, // 替换成自己开通一键登录的应用的 DCloud appid
    provider: 'univerify',
    apiKey: 'fc7aa3fb2672f947a501f2392a22501a', // 在开发者中心开通服务并获取 apiKey
    apiSecret: 'b4d9fafeb3c3ed12ff6cc97b9f9a1817', // 在开发者中心开通服务并获取 apiSecret
    access_token: event.access_token,
    openid: event.openid,
  })

  console.log(res) // res 里包含手机号

  // 执行用户信息入库等操作,正常情况下不要把完整手机号返回给前端
  // 在云函数中也可以调用后端接口将手机号存入后端数据中或云数据库中
  return {
    code: 200,
    message: '获取手机号成功',
  }
}
json
// uniCloud-aliyun/cloudfunctions/get-phone-number/package.json
{
  "name": "get-phone-number",
  "version": "1.0.0",
  "main": "index.js",
  "dependencies": {
    "uni-cloud-verify": {}
  }
}

关键行与易错点

  • 云函数默认生成的模板只是 return event,必须自己改成调用 uniCloud.getPhoneNumber 才能真正拿到手机号。
  • 必须在 package.json 中声明 uni-cloud-verify 依赖,漏加会直接报错,拿不到手机号。
  • apiKey / apiSecret 来自开发者中心开通一键登录后的基础配置,属于敏感信息,不要写进前端代码。
  • appid 使用 context.APPID(当前云空间对应的 DCloud AppID),与开通服务时的应用必须一致。
  • 一键登录是付费服务(按次计费),需要先充值才能成功调用。
  • 手机号属于敏感数据,不要把完整手机号返回给前端,应在云函数内直接入库。
  • 使用云函数前必须先开通 uniCloud 服务空间,并在 uniPush 后台把应用与服务空间关联。

示例 3:manifest.json 中的模块配置(消息推送 + 一键登录) ​

json
{
  "app-plus": {
    "modules": {
      "Push": "uniapp-2.0",
      "OAuth": {},
      "uni-oauth-univerify": {}
    },
    "distribute": {
      "sdkConfigs": {
        "push": {
          "unipush": {
            "version": "2",
            "offline": {
              "huawei": {
                "appid": "华为项目设置中的 APP ID",
                "appsecret": "华为项目设置中的 Secret",
                "packageName": "com.你的包名.test"
              }
            }
          }
        },
        "oauth": {
          "univerify": {
            "appid": "你的 DCloud AppID",
            "apiKey": "一键登录基础配置中的 apiKey",
            "apiSecret": "一键登录基础配置中的 apiSecret"
          }
        }
      }
    }
  }
}

关键行与易错点

  • 上述字段是通过 HBuilderX 的「App 模块配置」可视化勾选后生成的,实际以界面勾选结果为准,不要手写猜字段。
  • 消息推送:Push 选 2.0 版本并勾选「离线推送」,按手机品牌逐个配置(本例只演示华为),华为需要 appid、appsecret 和与打包时完全一致的包名。
  • 华为的 agconnect-services.json 需要下载后把内容整段粘贴到 uniPush 厂商推送设置的对应输入框,保存成功才说明配置正确。
  • 包名(PackageName)一旦确定就不能随意修改,uniPush 平台信息、华为应用、打包时填写的包名三处必须一字不差。
  • 一键登录需要勾选「OAuth 登录授权 → 一键登录」,勾选后重新打包(开发阶段用自定义调试基座,上线打正式包)才会生效。
  • 配置完成前不要急着发消息,必须重新打包并安装到手机上才能收到推送;推送有 1~数秒的延迟属正常现象。

常见错误 ​

  1. 后台显示"发送成功",手机上迟迟收不到消息 现象:uniPush 后台点确定后,手机要等很久才弹出通知,甚至完全没动静。 原因:App 端仍在使用旧的自定义基座(未包含本次 Push 配置),或离线推送厂商参数没有真正生效。 修法:确认 manifest.json 的模块设置里 Push 2.0 与离线推送厂商已勾选,重新打自定义调试基座并重装 App,再发一次消息验证。

  2. 云打包时报"签名证书有误",或打包成功但推送仍然失败 现象:云打包弹窗提示证书异常;或后台厂商推送配置保存失败。 原因:后台填写的 MD5、SHA1、SHA256 与云端证书不一致。常见于复制时把标题文字一起带上、只复制了部分字符、或三个值互相错位。 修法:打开云端证书详情,逐个值单独复制(只取冒号后面的值),粘贴后与证书页面对照核对一遍再保存。

  3. 包名前后不一致导致推送和登录全部失效 现象:本地调试正常,换个环境或重打包后推送、一键登录全部失灵。 原因:manifest.json 的包名、DCloud 后台各平台信息里的包名、厂商平台(华为等)创建应用时填的包名,三者不统一;开发中反复改包名(test/demo 混用)最容易出现。 修法:确定一个包名后全程不再改动,改动时同步更新所有平台,改完必须重新打包。

  4. 一键登录点下去没弹授权框,而是切换了登录方式 现象:App 里点手机号登录,界面只是切换 tab,没有出现授权弹层;或 H5 端直接报错。 原因:条件编译写错——平台标识写成 APP 而非 APP-PLUS,或 #ifdef / #ifndef 分支写反;也可能是 manifest 里没勾选 OAuth 的"一键登录"模块。 修法:核对条件编译的平台常量与分支逻辑,勾选模块后重新打包;改完代码确认已重新运行到手机(热更新有时不生效)。

  5. 云函数里 uniCloud.getPhoneNumber 报错或取不到手机号 现象:授权成功、access_token 也拿到了,但云函数执行失败。 原因:云函数的 package.json 未添加 uni-cloud-verify 依赖;或 apiKey / apiSecret 填错;或账户未充值(该接口按次计费)。 修法:在云函数依赖中加上 uni-cloud-verify 并重新上传部署,核对密钥与 appid,确认账户余额。

  6. 云函数本地调试时手机端调用不通 现象:模拟器/电脑端能调通,手机上调用云函数超时或失败。 原因:手机与电脑不在同一网络下。 修法:让手机和电脑连接同一个 Wi-Fi 再调试;需要断点调试时先在 HBuilderX 里开启断点调试插件。

练习 ​

  1. 在 uniPush 后台给测试账号发一条标题为"课堂演练"的消息,分别在"未重新打包"和"重新打包自定义基座"两种状态下各发一次,记录到达时间差,并写出你的排查结论。

  2. 打开云端证书详情,把 MD5、SHA1、SHA256 三个值分别填入 DCloud 后台的安卓平台信息并提交。提交后故意把其中一个值少复制一位,观察系统提示,说明系统是如何校验的。

  3. 在登录页实现:App 端点击"手机号登录"唤起一键登录授权框,非 App 端仍走原有 tab 切换逻辑。写完后分别用自定义基座和 H5 各验证一次,说明条件编译生效的判断依据。

  4. 为授权框定制样式:替换 logo 为本地图片、按钮主色改为红色、隐私协议勾选框使用自定义的选中/未选中图标。改完后说明哪些配置项只在全屏模式下生效。

  5. 编写一个云函数,接收客户端传来的 access_token 与 openid,调用 uniCloud.getPhoneNumber 取手机号,并只向前端返回"是否成功"而不返回完整号码。写出你在云函数依赖、密钥、计费三方面需要提前确认的事项。

原视频对照 ​

#视频时长
1消息推功能介绍04:29
2消息推送-添加并完善应用信息12:33
3消息推送-配置华为项目和应用12:29
4消息推送-云打包应用04:40
5一键登录-功能介绍07:19
6一键登录-开通服务14:55

小结 ​

  1. 地图、推送、一键登录这三块功能有一个共同前提:包名与证书信息必须全局一致,任何一处对不上都会导致功能静默失效,而不是报错。
  2. 推送的关键链路是"后台配置 → manifest 勾选模块 → 重新打包 → 装机验证",跳过重新打包这一步是最常见的失败原因,热更新无法让新模块生效。
  3. 离线推送是"按厂商逐个配置"的模式,用户手机品牌不确定就意味着理论上都要配;课堂练习只配华为是为了降低操作成本,不代表生产环境可以只配一家。
  4. 一键登录本质是"客户端拿授权凭证 + 云函数换手机号"两段式流程,客户端只能拿到凭证,真正的手机号只能在服务端/云函数侧获取,前端不应接触完整号码。
  5. 云函数的能力是有边界的:依赖要显式声明、密钥要单独配置、接口要按次付费,这三点决定了它不能像普通前端函数那样"写完就能跑"。
  6. 条件编译是跨端项目处理平台差异的标准手段,但它的平台常量(APP-PLUS 等)和分支方向极易写错,改完必须真机验证,不能只看代码逻辑。
  7. 一键登录的"添加应用"需要审核,正式包上线前必须提前申请;开发阶段用标准基座可以绕过等待,但上线前一定要回头补齐。
  8. 这类第三方平台配置工作步骤多、容错低,建议把每个平台的配置项(包名、SHA1、AppID、Secret)整理成一份对照表存档,重装或换人时可直接复用。