Call a CloudBase Cloud Function in WeChat Mini Program
In one sentence: Use
wx.cloud.callFunctionto connect directly to a Cloud Function. The Cloud Function side useswx-server-sdkto automatically obtain the OPENID/APPID/UNIONID — no custom identity system, no HTTPS domain, and no token validation needed.Estimated time: 25 minutes | Difficulty: Beginner
Applicable Scenarios
This path follows the WeChat Cloud Development system for calling Cloud Functions from a Mini Program frontend. It is a different chain from the @cloudbase/js-sdk custom login used in add-database-wechat-miniprogram — do not mix the two.
- Applicable: Cloud Development is already enabled in the Mini Program (
wx.cloud.initworks), and you want to call server-side logic that obtains the OPENID from the frontend - Applicable: Business logic requires the OPENID (sending template/subscribe messages, looking up existing user bindings, generating identity-tagged QR codes)
- Applicable: You do not want to build an HTTPS service or maintain token refresh logic in the Mini Program
- Not applicable: Calling the same Cloud Function from H5 / Web — that requires the HTTP trigger covered in connect-openai-api-cloud-function
- Not applicable: You have already migrated from WeChat Cloud Development to a standalone CloudBase environment — see migrate-wxcloud-to-cloudbase
Prerequisites
| Dependency | Version |
|---|---|
| Mini Program Base Library | ≥ 2.2.3 (minimum version for wx.cloud) |
wx-server-sdk | 3.0.1 |
@cloudbase/cli (optional) | 1.27.0+, for deploying via the tcb CLI |
| WeChat DevTools | ≥ 1.06.x |
Also required:
- An active CloudBase environment with an environment ID in the format
your-env-id-1234567 - The Mini Program AppID is bound to this environment in the CloudBase Console under Environment Settings → Security Settings → Mini Program Association
Step 1: Associate the Mini Program AppID with the CloudBase Environment in the Console
Go to the CloudBase Console → select your environment → Environment Settings → Security Settings → Mini Program Association, and add your Mini Program's AppID.
This step is the root of wx.cloud.init({ env }) authentication: the Mini Program base library asks the cloud whether this AppID is permitted to use this env. If the association record does not exist, it immediately returns "invalid env", and all Cloud Function calls, Cloud Database reads and writes, and Cloud Storage uploads will fail.
Complete this step before writing any code; otherwise Step 3's console will only show a semantically unclear errMsg.
Step 2: Write the Cloud Function (wx-server-sdk + getWXContext)
Create a new Cloud Function directory (in WeChat DevTools, right-click under cloudfunctions/ in the project root → New Node.js Cloud Function, name it add). It contains two files: index.js and package.json.
// cloudfunctions/add/index.js
const cloud = require('wx-server-sdk');
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext();
return {
sum: event.x + event.y,
openid: wxContext.OPENID,
appid: wxContext.APPID,
unionid: wxContext.UNIONID,
};
};
// cloudfunctions/add/package.json
{
"name": "add",
"version": "1.0.0",
"main": "index.js",
"dependencies": {
"wx-server-sdk": "3.0.1"
}
}
Three details worth noting:
cloud.DYNAMIC_CURRENT_ENVtells the Cloud Function runtime to automatically use the environment it is deployed in. No code change is needed for cross-environment deployments. This is the standard pattern since thelatestversion.- The OPENID/APPID/UNIONID returned by
cloud.getWXContext()are propagated end-to-end from the base library through to the Cloud Function. They are not fields in the request body, cannot be modified or forged by business code, and can be used directly as identity. - An unauthenticated guest call (e.g., a shared page without authorization) still has an
OPENIDvalue (a session-based temporary openid), butUNIONIDmay be an empty string. Handle the empty-value case in your business logic.
event is a direct pass-through of the data field from the Mini Program; anything JSON-serializable works. The object returned by return becomes res.result on the frontend. Do not return Date instances (serialization loses timezone information; convert to an ISO string before returning).
If the Cloud Function needs to access the database, storage, or call another Cloud Function, wx-server-sdk already encapsulates the clients. Identity is reused directly from the OPENID obtained via getWXContext() — no additional token signing is required:
// Read from the database inside a Cloud Function
const db = cloud.database();
const user = await db.collection('users').where({ _openid: wxContext.OPENID }).get();
// Call another Cloud Function inside a Cloud Function
const res = await cloud.callFunction({ name: 'sendMessage', data: { ... } });
This is the core value of BaaS-style calls: identity flows in a straight line from client to Cloud Function to database. Business code never sees a token and never needs to manage renewal.
Step 3: Mini Program Side — wx.cloud.init + wx.cloud.callFunction
wx.cloud.callFunction supports both Promise and callback styles:
- Promise / async-await: Use for serial multi-step page logic; exceptions go through
try / catch. Best readability — the right choice for 90% of cases. - callback (
success/fail): Use when the base library is older or when sharing a callback-style utility with otherwx.*APIs (e.g., a legacywx.requestwrapper). No extraPromise.resolvelayer needed.
Initialize once globally in app.js:
// app.js
App({
onLaunch() {
if (!wx.cloud) {
console.error('请使用 2.2.3 或以上的基础库以使用云能力');
return;
}
wx.cloud.init({
env: 'your-env-id-1234567',
traceUser: true,
});
},
});
traceUser: true records each session's openid and last-active time in the CloudBase Console under User Management, making it easy to view daily DAU directly in the console. Leaving it off does not affect functionality.
Calling from a page using the Promise form:
// pages/index/index.js
Page({
async onTapAdd() {
try {
const res = await wx.cloud.callFunction({
name: 'add',
data: { x: 1, y: 2 },
});
console.log('result:', res.result);
// { sum: 3, openid: 'oABC...', appid: 'wxXXX...', unionid: '' }
} catch (err) {
console.error('callFunction failed', err);
}
},
});
The callback form is also supported — pass success / fail callbacks as an alternative to the Promise form:
wx.cloud.callFunction({
name: 'add',
data: { x: 1, y: 2 },
success: (res) => console.log(res.result),
fail: (err) => console.error(err),
});
name is the Cloud Function name (not a file path). data goes directly into the Cloud Function's event. The size limit is 5 MB. The return value is in res.result, not res.data — this is the most common point of confusion with wx.request.
Two common use cases in business logic:
-
Temporary cross-environment switching: When you have separate test and production environments, specify the environment for a single
callFunctioncall without touching the globalwx.cloud.initconfig:await wx.cloud.callFunction({name: 'add',data: { x: 1, y: 2 },config: { env: 'test-env-id-1234567' },}); -
Timeout control:
wx.cloud.callFunctionhas notimeoutparameter — the frontend waits until the Cloud Function returns. If the Cloud Function may run for 20+ seconds (e.g., calling an external LLM), either cap the timeout inside the Cloud Function and return early, or wrap the frontend call withPromise.raceto set a timeout. Do not block the UI indefinitely.
Step 4: Deploy via tcb CLI or WeChat DevTools
Pick one of the two options.
A. WeChat DevTools (recommended for getting started)
Right-click the cloudfunctions/add/ directory → Upload and Deploy: Install Dependencies on Cloud (do not upload node_modules) → wait ~30 seconds → once you see "Upload successful", the Cloud Function is callable from the Mini Program.
B. CLI (tcb command, recommended for CI / automation)
# Install the CLI
npm install -g @cloudbase/cli
# Deploy a single event-triggered function (no --httpFn, since this is for Mini Program callFunction)
tcb fn deploy add -e your-env-id-1234567
After deployment, go to the Console → Cloud Development → Functions → Function List to find add. Click in to view runtime memory, timeout settings, and recent invocation logs.
Note: --httpFn is for HTTP triggers (called via a public domain). Mini Program callFunction uses "event trigger" mode. Adding --httpFn will make the function unreachable via callFunction from the Mini Program. A Cloud Function can have both event trigger and HTTP trigger attached simultaneously, but requests arriving via the HTTP trigger do not carry wxContext.OPENID — only event-triggered calls automatically propagate identity.
tcb fn deploy reads dependencies from cloudfunctions/<name>/package.json by default and runs npm install on the cloud. No local node_modules installation is required. If you use a private npm registry or need to lock versions, place a .npmrc and package-lock.json in the directory beforehand.
Step 5: Add Logging Inside the Cloud Function (Optional but Strongly Recommended)
Cloud Functions have no "local console". All console.log / console.error output goes to cloud logs, and debugging depends on them:
exports.main = async (event, context) => {
console.log('[add] event =', event);
const wxContext = cloud.getWXContext();
console.log('[add] wxContext =', wxContext);
// ... business logic
};
Two ways to view logs:
- WeChat DevTools: left panel → Cloud Development → Functions → Logs — shows the last 24 hours only
- CloudBase Console → Cloud Development → Functions → Function List → select function → Log Query — filter by time range, keyword, or RequestId; retained for 7 days
During development, log one line of event and wxContext at each Cloud Function entry point. When something goes wrong, the first thing you see is "are the incoming parameters and identity correct?" — far more informative than the errMsg on the frontend side. In production, reduce to logging only error-level messages as appropriate.
Verification
- Compile and run in WeChat DevTools; trigger the button that calls
wx.cloud.callFunction - The DevTools Console should show
result: { sum: 3, openid: 'o...', appid: 'wx...', unionid: '...' }—summust equal 3 - Console → Cloud Development → Functions → add → Log Query, select the last 5 minutes; you should see one INFO-level run record where
eventis{ x: 1, y: 2 }andreturnValuematches what the frontend received - Comment out the
cloud.initline in the Cloud Function, redeploy, and call again — the frontend should return an error saying "please call init first". This confirms the full chain actually reaches the Cloud Function and is not cached by any intermediate layer
Remember to revert the code after Step 4.
If Step 3 shows no log entry in the Console but the frontend Console received res.result, the deployment almost certainly did not take effect — DevTools sometimes caches the previous deployment zip. To force a fresh build: delete the local cloudfunctions/add/node_modules directory, right-click the directory → Clear Cache and Redeploy, then call again.
Common Errors
| Error message | Cause | Fix |
|---|---|---|
errCode: -404011 cloud function execution error or "invalid env" in console | The AppID was not associated with this env in Step 1, or the environment ID is wrong | In the Console under Environment Settings → Security Settings → Mini Program Association, add the current Mini Program's AppID. Confirm that the env in wx.cloud.init({ env }) matches the Console environment ID exactly (don't omit the trailing random string) |
Cloud API isn't enabled, please call wx.cloud.init first | wx.cloud.callFunction is called directly in a page, but wx.cloud.init was not called in app.js onLaunch, or the base library is below 2.2.3 | Move wx.cloud.init into app.js onLaunch; also ensure cloudfunctionRoot is set in project.config.json |
errCode: -501005 FUNCTIONS_EXECUTE_FAIL function not exists | Function name is mistyped, or the function was written locally but never uploaded | Check that the name field exactly matches the cloud function name (case-sensitive). The function must appear in the Console's function list to be considered successfully deployed |
wxContext.OPENID is undefined | cloud.init was not called via wx-server-sdk, or the parameter name in event shadows context | The Cloud Function must call cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) at the top before getWXContext() has data. Do not name the parameter something like (event, wxContext) |
| First response after deployment is 3–5 seconds slow | Cold start of the function instance | This is expected behavior. After the Node.js 12/16 runtime cold-starts once, the instance is kept alive for 5–10 minutes. For high-frequency scenarios, see optimize-cloud-function-wechat-miniprogram |
errCode: -601001 RESOURCE_INSUFFICIENT | Monthly free quota exhausted, or pay-as-you-go account is in arrears | Console → Usage → Resource Usage to check the current month's quota. A pay-as-you-go account in arrears is suspended 24 hours after the arrears occur |
errMsg: cloud.callFunction:fail Error: errCode: -502005 DATABASE_PERMISSION_DENIED | The Cloud Function is accessing the database, but the collection permission is "Only creator can read and write" and the calling OPENID is not the document creator | The Cloud Function's execution identity inherits the caller's OPENID, not admin. To bypass permissions and read the full collection, explicitly obtain an admin client with cloud.database({ env: ... }) inside the Cloud Function, or change the collection permission to "Only admin can read and write" |
For the complete error code definitions, see error-code.
The errCode received on the frontend is generally passed through from the cloud. First use the error code to determine whether the issue is "can't reach the function" (-404 / -501) or "reached the function but it crashed" (-502 / -601), then decide whether to check the frontend logs or Cloud Function logs. This is far more efficient than searching the error message directly.
Related Documentation
- add-database-wechat-miniprogram — the alternative chain using
@cloudbase/js-sdkcustom login to access the database directly; distinct from this article - fix-auth-wechat-miniprogram — fallback troubleshooting for Mini Program login state and AppID association issues
- connect-openai-api-cloud-function — how to add an HTTP trigger to the same Cloud Function for non-Mini Program clients
- optimize-cloud-function-wechat-miniprogram — cold start, concurrency, and timeout tuning once the call chain is working