内建账户指南
从 TapSDK 3.0 开始,我们提供了一个内建账户系统供游戏使用:开发者可以直接用 TapTap OAuth 授权的结果生成一个游戏内的账号(TDSUser
),同时我们也支持将更多第三方认证登录的结果绑定到该账号上来。
TapSDK 提供的游戏内好友、成就等服务和功能,也都基于这一账户系统。
环境要求
- Unity
- Android
- iOS
- UE4
- Unity 2019.4 或更高版本
- iOS 11 或更高版本,Xcode 版本 14.1 或更高版本
- Android 5.0(API level 21)或更高版本
Android 5.0(API level 21)或更高版本
iOS 11 或更高版本,Xcode 版本 14.1 或更高版本
- 安装 UE 4.26 及以上版本
- iOS 12 或更高版本
- Android 5.0(API level 21)或更高版本
- macOS 10.14.0 或更高版本
- Windows 7 或更高版本
支持平台:Android / iOS / Windows / macOS
权限说明
- Unity
- Android
- iOS
- UE4
该模块需要如下权限:
权限 | 使用目的 | 权限申请时机 |
---|---|---|
网络权限 | 用于访问网络数据 | 用户首次使用该功能时会申请权限 |
该模块将在应用中添加如下权限:
<uses-permission android:name="android.permission.INTERNET"/>
集成前准备
- 参考 准备工作 创建应用、开启内建账户应用服 务、绑定 API 域名;
SDK 获取
- Unity
- Android
- iOS
- UE4
SDK 可以通过 Unity Package Manager 导入或手动导入,二者任选其一。请根据项目需要选择。
方法一:使用 Unity Package Manager
NPMJS 安装
从 3.25.0 版本开始,TapSDK 支持了 NPMJS 安装,优势是只需要配置版本号,并且支持嵌套依赖。
在项目的 Packages/manifest.json
文件中添加以下依赖:
"dependencies":{
"com.taptap.tds.bootstrap":"3.29.7",
"com.taptap.tds.login":"3.29.7",
"com.taptap.tds.common":"3.29.7",
}
但需要注意的是,要在 Packages/manifest.json
中 dependencies
同级下声明 scopedRegistries
:
"scopedRegistries": [
{
"name": "NPMJS",
"url": "https://registry.npmjs.org/",
"scopes": ["com.tapsdk", "com.taptap", "com.leancloud"]
}
]
GitHub 安装
在项目的 Packages/manifest.json
文件中添加以下依赖:
"dependencies":{
"com.taptap.tds.login":"https://github.com/TapTap/TapLogin-Unity.git#3.29.7",
"com.taptap.tds.common":"https://github.com/TapTap/TapCommon-Unity.git#3.29.7",
"com.taptap.tds.bootstrap":"https://github.com/TapTap/TapBootstrap-Unity.git#3.29.7",
"com.leancloud.realtime":"https://github.com/leancloud/csharp-sdk-upm.git#realtime-2.3.0",
"com.leancloud.storage":"https://github.com/leancloud/csharp-sdk-upm.git#storage-2.3.0",
}
在 Unity 顶部菜单中选择 Window > Package Manager 可查看已经安装在项目中的包。
方法二:手动导入
-
在 下载页 找到 TapSDK Unity 下载地址,下载
TapSDK-UnityPackage.zip
。 -
在 Unity 项目中依次转到 Assets > Import Packages > Custom Packages,从解压后的
TapSDK-UnityPackage.zip
中,选择希望在游戏中使用的 TapSDK 包导入,其中:
TapTap_Bootstrap.unitypackage
TapSDK 启动器,必选。TapTap_Common.unitypackage
TapSDK 基础库,必选。TapTap_Login.unitypackage
TapTap 登录库,必选。
- 从 LeanCloud-SDK 下载页 中下载并解压 LeanCloud-SDK-Storage-Unity.zip,然后将 Plugins 文件夹拖拽至 Unity 即可。
iOS 配置
在 Assets/Plugins/iOS/Resource
目录下创建 TDS-Info.plist
文件,复制以下代码并且替换其中的 ClientId
。如果游戏使用了 TapTap 内嵌动态或数据分析服务,需要配置相关权限并替换授权文案:
复制使用以下内容时,请删除空行以及注释,以免出现 XML 解析时报错,ApplicationException: expected a key node
。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>taptap</key>
<dict>
<key>client_id</key>
<string>ClientId</string>
</dict>
<!--使用内嵌动态服务,需要相册、相机、麦克风权限-->
<key>NSPhotoLibraryUsageDescription</key>
<string>说明为何应用需要此项权限</string>
<key>NSCameraUsageDescription</key>
<string>说明为何应用需要此项权限</string>
<key>NSMicrophoneUsageDescription</key>
<string>说明为何应用需要此项权限</string>
<!--使用数据分析服务需要 IDFA 权限。如应用程序不想弹框,可以设置 TapDB.AdvertiserIDCollectionEnabled(false)-->
<key>NSUserTrackingUsageDescription</key>
<string>说明为何应用需要此项权限</string>
</dict>
</plist>
-
下载 TapSDK Android,解压后选择需要用到的 SDK 包导入到项目
project/app/libs
目录下。 -
打开项目的
project/app/build.gradle
文件,添加 gradle 配置如下:
dependencies {
...
// 导入 libs 目录下所有 aar 的包:
implementation fileTree(dir: 'libs', include: ['*.aar'])
// 如果需要单独导入 libs 目录下的指定包,请按照如下方式:
implementation files('libs/TapBootstrap_3.29.7.aar') // TapTap 启动器
implementation files('libs/TapCommon_3.29.7.aar') // TapTap 基础库
implementation files('libs/TapLogin_3.29.7.aar') // TapTap 登录
implementation 'com.taptap:lc-storage-android:8.2.24' // 数据存储
implementation 'com.taptap:lc-realtime-android:8.2.24'
}
-
旧版 Android 额外配置
如果
targetSdkVersion < 29
,还需要添加如下配置:manifest
节点添加xmlns:tools="http://schemas.android.com/tools"
application
节点添加tools:remove="android:requestLegacyExternalStorage"
导入 SDK
-
在 Xcode 选择工程,到 Build Setting > Other Linker Flags 添加
-ObjC
和-Wl -ld_classic
。 -
下载 TapSDK iOS,解压后选择需要导入的资源文件,直接拖拽到项目目录即可。
-
视需要导入下载的资源文件:
-
必选:TapTap 启动器、基础库、登录
TapBootstrapSDK.framework
TapCommonSDK.framework
TapLoginSDK.framework
LeanCloudObjc.framework
TapCommonResource.bundle
TapLoginResource.bundle
// 3.29.4 版本需要添加 LibProtocolBuffers
LibProtocolBuffers.framework
-
-
请仔细核对下面依赖库是否都添加成功:
// 必选
WebKit.framework
Security.framework
SystemConfiguration.framework
CoreTelephony.framework
SystemConfiguration.framework
libc++.tbd
// TapTap 内嵌动态
AVFoundation.framework
CoreTelephony.framework
MobileCoreServices.framework
Photos.framework
SystemConfiguration.framework
WebKit.framework
// 数据分析
// 如果不需要获取 IDFA 则不要添加 `AppTrackingTransparency` 和 `AdSupport` 两个系统库
AppTrackingTransparency.framework
AdSupport.framework
CoreMotion.framework
Security.framework
SystemConfiguration.framework
libresolv.tbd
libsqlite3.0.tbd
libz.tbd
配置权限
如果游戏使用了 TapTap 内嵌动态或数据分析服务,那么需要在 info.plist
配置相关权限并替换授权文案:
<!--使用内嵌动态服务, 需要相册、相机、麦克风权限-->
<key>NSPhotoLibraryUsageDescription</key>
<string>说明为何应用需要此项权限</string>
<key>NSCameraUsageDescription</key>
<string>说明为何应用需要此项权限</string>
<key>NSMicrophoneUsageDescription</key>
<string>说明为何应用需要此项权限</string>
<!--使用数据分析服务需要 IDFA 权限。如应用程序不想弹框,可以设置 TapDB.AdvertiserIDCollectionEnabled(false)-->
<key>NSUserTrackingUsageDescription</key>
<string>说明为何应用需要此项权限</string>
配置跳转 TapTap 应用
用户无 TapTap 应用时,默认会通过 WebView 登录。
-
打开
info.plist
,添加如下配置(请替换clientID
为你在控制台获取的 Client ID):<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>taptap</string>
<key>CFBundleURLSchemes</key>
<array>
<!-- 这里注意下,中括号需要去掉,最终是 Client ID 前拼接上 `tt` 的形式,例如:ttFwFdCxxxxxxxQDQwQN -->
<string>tt[clientID]</string>
</array>
</dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>tapiosdk</string>
<string>tapsdk</string>
<string>taptap</string>
</array> -
配置 openUrl:
a) 如果项目中有
SceneDelegate.m
,请先删除,然后请添加如下代码到AppDelegate.m
文件:- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [TDSHandleUrl handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
return [TDSHandleUrl handleOpenURL:url];
}b) 删除
info.plist
里面的 Application Scene Manifestc) 删除
AppDelegate.m
文件中的两个管理Scenedelegate
生命周期代理方法#pragma mark - UISceneSession lifecycle
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}
- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
}d) 在
AppDelegate.h
中添加UIWindow
@property (strong, nonatomic) UIWindow *window;
- 下载 TapSDK UE4,TapSDK-UE4-xxx.zip 解压后将
TapBootstrap
、TapCommon
、TapLogin
文件夹 Copy 到项目的Plugins
目录中 - 重启 Unreal Editor
- 打开 编辑 > 插件 > 项目 > TapTap,开启
TapBootstrap
和TapLogin
模块
添加依赖
在 Project.Build.cs 中添加所需模块:
PublicDependencyModuleNames.AddRange(new string[] { "Core",
"CoreUObject",
"Engine",
"Json",
"InputCore",
"JsonUtilities",
"SlateCore",
"TapCommon",
"TapBootstrap",
"TapLogin"
});
if (Target.Platform == UnrealTargetPlatform.IOS || Target.Platform == UnrealTargetPlatform.Android)
{
PublicDependencyModuleNames.AddRange(
new string[]
{
// 推送接入
// "LeanCloudPush",
"LeanCloudMobile"
}
);
}
else
{
PublicDependencyModuleNames.AddRange(
new string[]
{
"LeanCloud"
}
);
}
导入头文件
#include "TapBootstrap.h"
点击展开 iOS 配置
在 项目设置 > Platform > iOS > Additional Plist data 中可以填入一个字符串,复制以下代码并且替换其中的 ClientID
以及授权文案。
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>taptap</string>
<key>CFBundleURLSchemes</key>
<array>
<!-- 这里注意下,花括号需要去掉,最终是 ClientID 前拼接上 `tt` 的形式,例如:ttFwFdCxxxxxxxQDQwQN -->
<string>tt{ClientID}</string>
</array>
</dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>tapiosdk</string>
<string>tapsdk</string>
<string>taptap</string>
</array>
如果接入 TapDB 模块,那么还需要加上:
<key>NSUserTrackingUsageDescription<key>
<string>{数据追踪权限申请文案}</string>
SDK 初始化
初始化 TapSDK 时需传入 Client ID
、区域等应用配置信息。
- Unity
- Android
- iOS
- UE4
using TapTap.Bootstrap; // 命名空间
using TapTap.Common; // 命名空间
var config = new TapConfig.Builder()
.ClientID("your_client_id") // 必须,开发者中心对应 Client ID
.ClientToken("your_client_token") // 必须,开发者中心对应 Client Token
.ServerURL("https://your_server_url") // 必须,开发者中心 > 你的游戏 > 游戏服务 > 基本信息 > 域名配置 > API
.RegionType(RegionType.CN) // 非必须,CN 表示中国大陆,IO 表示其他国家或地区
.ConfigBuilder();
TapBootstrap.Init(config);
请确保 TapSDK 的初始化在主线程(UI 线程)中执行。
TapConfig tdsConfig = new TapConfig.Builder()
.withAppContext(MainActivity.this) // Context 上下文
.withClientId("your_client_id") // 必须,开发者中心对应 Client ID
.withClientToken("your_client_token") // 必须,开发者中心对应 Client Token
.withServerUrl("https://your_server_url") // 必须,开发者中心 > 你的游戏 > 游戏服务 > 基本信息 > 域名配置 > API
.withRegionType(TapRegionType.CN) // TapRegionType.CN:中国大陆,TapRegionType.IO:其他国家或地区
.build();
TapBootstrap.init(MainActivity.this, tdsConfig);
// 开发者必须至少依赖 `TapBootstrap`、`TapLogin`、`TapCommon` 以及 `LeanCloudObjc` 模块,并按照如下方式完成初始化:
TapConfig *config = [TapConfig new];
config.clientId = @"your_client_id"; // 必须,开发者中心对应 Client ID
config.clientToken = @"your_client_token"; // 必须,开发者中心对应 Client Token
config.serverURL = @"https://your_server_url"; // 必须,开发者中心 > 你的游戏 > 游戏服务 > 基本信息 > 域名配置 > API
config.region = TapSDKRegionTypeCN; // TapSDKRegionTypeCN:中国大陆,TapSDKRegionTypeIO:其他国家或地区
[TapBootstrap initWithConfig:config];
TapBootstrap
初始化方法会把直接初始化 TapLogin 模块,如果插件中包含 TapDB 并且 DBConfig.Enable = true
,那么也会完成 TapDB
初始化。
这两个模块无需再次初始化。
FTUConfig Config;
Config.ClientID = "your_client_id"; // 必须,开发者中心对应 Client ID
Config.ClientToken = "your_client_token"; // 必须,开发者中心对应 Client Token
Config.ServerURL = "https://your_server_url"; // 必须,开发者中心 > 你的游戏 > 游戏服务 > 基本信息 > 域名配置 > API
Config.RegionType = ERegionType::CN; // ERegionType::CN:中国大陆,ERegionType::Global:其他国家或地区
FTapBootstrap::Init(Config);
初始化的时候,必须填入 client_id
、client_token
和 server_url
,其中:
-
client_id
、client_token
信息可在 开发者中心 > 你的游戏 > 游戏服务 > 应用配置 查看。 -
server_url
请使用 HTTPS 协议,参考文 档关于 域名 的说明。
TDSUser
和 LCUser
TDSUser
类继承自 LCUser
类。
LCUser
是 LeanCloud 提供的账户系统,TDSUser
基本沿用了其功能和接口,并针对 TDS 的需求进行了细微调整,所以我们推荐大家使用 TDSUser
类来构建玩家账户系统。
TapTap 登录
直接调用一键登录方法即可,详见接入 TapTap 登录。
游客登录
内建账户系统支持玩家在游戏中创建一个游客账号,其调用示例如下:
- Unity
- Android
- iOS
- UE4
try{
// 通过 tdsUSer 给出用户唯一标识,如果有的话
var tdsUser = await TDSUser.LoginAnonymously();
}catch(Exception e){
// 登录失败
Debug.Log($"{e.code} : {e.message}");
}
TDSUser.logInAnonymously().subscribe(new Observer<TDSUser>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(TDSUser resultUser) {
// 登录成功,得到一个账户实例
String userId = resultUser.getObjectId();
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
}
});
[TDSUser loginAnonymously:^(TDSUser * _Nullable user, NSError * _Nullable error) {
if (user) {
NSString *userId = user.objectId;
} else {
NSLog(@"%@", error);
}
}];
FTDSUser::LoginAnonymously(FTDSUser::FCallBackDelegate::CreateLambda([](const TSharedPtr<FTDSUser>& UserPtr, const FTUError& Error) {
if (UserPtr.IsValid()) {
FString UserID = UserPtr->GetObjectId();
} else {
// 登录失败 Error.msg;
}
}));
这里的「游客账户」可以保证玩家在同一个设备上多次登录都得到同一个账户,但是如果玩家卸载游戏重装之后再以「游客」身份登录则无法保证账户的唯一性。
当前用户
用户登录后,SDK 会自动将会话信息存储到客户端,这样用户在下次打开客户端时无需再次登录。下面的代码检查是否有已经登录的用户:
- Unity
- Android
- iOS
- UE4
TDSUser currentUser = await TDSUser.GetCurrent();
if (currentUser != null) {
// 跳到首页
} else {
// 显示注册或登录页面
}
TDSUser currentUser = TDSUser.getCurrentUser();
if (currentUser != null) {
// 跳到首页
} else {
// 显示注册或登录页面
}
TDSUser *currentUser = [TDSUser currentUser];
if (currentUser != nil) {
// 跳到首页
} else {
// 显示注册或登录页面
}
TSharedPtr<FTDSUser> CurrentUser = FTDSUser::GetCurrentUser();
if (CurrentUser.IsValid()) {
// 跳到首页
} else {
// 显示注册或登录页面
}
会话信息会长期有效,直到用户主动登出:
- Unity
- Android
- iOS
- UE4
await TDSUser.Logout();
// currentUser 变为 null
TDSUser currentUser = await TDSUser.GetCurrent();
TDSUser.logOut();
// currentUser 变为 null
TDSUser currentUser = TDSUser.getCurrentUser();
[TDSUser logOut];
// currentUser 变为 nil
TDSUser *currentUser = [TDSUser currentUser];
FTDSUser::Logout();
// CurrentUser 变为 nullptr
TSharedPtr<FTDSUser> CurrentUser = FTDSUser::GetCurrentUser();
设置当前用户
用户登录后,云端会返回一个 session token 给客户端,它会由 SDK 缓存起来并用于日后同一 TDSUser
的鉴权请求。session token 会被包含在每个客户端发起的 HTTP 请求的 header 里面,这样云端就知道是哪个 TDSUser
发起的请求了。
以下是一些应用可能需要用到 session token 的场景:
- 应用根据以前缓存的 session token 登录(可以通过
sessionToken
属性获取到当前用户的 session token;在服务端等受信任的环境下,可以通过 Master Key(即 Server Secret)读取任意用户的sessionToken
字段以获取 session token)。 - 应用内的某个 WebView 需要知道当前登录的用户。
- 在服务端登录后,返回 session token 给客户端,客户端根据返回的 session token 登录。
下面的代码使用 session token 登录一个用户(云端会验证 session token 是否有效):
- Unity
- Android
- iOS
- UE4
await TDSUser.BecomeWithSessionToken("anmlwi96s381m6ca7o7266pzf");
TDSUser.becomeWithSessionTokenInBackground("anmlwi96s381m6ca7o7266pzf").subscribe(new Observer<TDSUser>() {
public void onSubscribe(Disposable disposable) {}
public void onNext(TDSUser user) {
// 修改 currentUser
TDSUser.changeCurrentUser(user, true);
}
public void onError(Throwable throwable) {
// session token 无效
}
public void onComplete() {}
});
[TDSUser becomeWithSessionTokenInBackground:@"anmlwi96s381m6ca7o7266pzf" block:^(TDSUser * _Nullable user, NSError * _Nullable error) {
if (user != nil) {
// 登录成功
} else {
// session token 无效
}
}];
FTDSUser::BecomeWithSessionToken("anmlwi96s381m6ca7o7266pzf", FTDSUser::FCallBackDelegate::CreateLambda([](const TSharedPtr<FTDSUser>& UserPtr, const FTUError& Error) {
if (UserPtr.IsValid()) {
FString UserID = UserPtr->GetObjectId();
} else {
// 登录失败 Error.msg;
}
}));
请避免在外部浏览器使用 URL 来传递 session token,以防范信息泄露风险。
如果在 开发者中心 > 你的游戏 > 游戏服务 > 云服务 > 内建账户 > 设置 中勾选了 密码修改后,强制客户端重新登录,那么当一个用户修改密码后,该用户的 session token 会被重置。此时需要让用户重新登录,否则会遇到 403 (Forbidden)
错误。
下面的代码检查 session token 是否有效:
- Unity
- Android
- iOS
- UE4
TDSUser currentUser = await TDSUser.GetCurrent();
bool isAuthenticated = await currentUser.IsAuthenticated();
if (isAuthenticated) {
// session token 有效
} else {
// session token 无效
}
boolean authenticated = TDSUser.getCurrentUser().isAuthenticated();
if (authenticated) {
// session token 有效
} else {
// session token 无效
}
TDSUser *currentUser = [TDSUser currentUser];
NSString *token = currentUser.sessionToken;
[currentUser isAuthenticatedWithSessionToken:token callback:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// session token 有效
} else {
// session token 无效
}
}];
TSharedPtr<FTDSUser> User = FTDSUser::GetCurrentUser();
if (User.IsValid() && User->IsAuthenticated()) {
// session token 有效
} else {
// session token 无效
}
设置其他用户属性
开发者可以使用内建账户系统设置 nickname
和 avatar
,比如通过设置 nickname
字段来添加昵称:
- Unity
- Android
- iOS
- UE4
var currentUser = await TDSUser.GetCurrent(); // 获取当前登录的账户实例
currentUser["nickname"] = "Tarara";
await currentUser.Save();
TDSUser currentUser = TDSUser.currentUser(); // 获取当前登录的账户实例
currentUser.put("nickname", "Tarara");
currentUser.saveInBackground().subscribe(new Observer<LCObject>() {
@Override
public void onSubscribe(@NotNull Disposable d) {
}
@Override
public void onNext(@NotNull LCObject lcObject) {
// 保存成功,currentUser 的属性得到更新
TDSUser tdsUser = (TDSUser) lcObject;
}
@Override
public void onError(@NotNull Throwable e) {
}
@Override
public void onComplete() {
}
});
TDSUser *currentUser = [TDSUser currentUser];
currentUser[@"nickname"] = @"Tarara";
[currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// 保存成功
} else {
NSLog(@"%@", error);
}
}];
TSharedPtr<FTDSUser> User = FTDSUser::GetCurrentUser();
User->SetNickName(TEXT("Tarara"));
User->Save(FTDSUser::FCallBackDelegate::CreateLambda([](const TSharedPtr<FTDSUser>& UserPtr, const FTUError& Error) {
if (UserPtr.IsValid()) {
// 保存成功
} else {
// 登录失败 Error.msg;
}
}));
内建账户系统只支持内置字段和两个自定义字段: nickname
(昵称) 以及 avatar
(头像),添加其他新的字段会报错。
内建账户系统保存了用户的鉴权信息,也可能保存了邮箱、手机等敏感信息,因此会设置非常严格的权限,以防用户信息泄露。另外,在内建账户系统中保存过多数据,也容易导致慢查询等性能问题。所以,我们限制了自定义字段的使用,如需保存其他的用户信息,建议另外创建专门的 Class(比如 UserProfile
)。
建议开发者使用 nickname
字段存储昵称信息,TDS 游戏好友模块 根据昵称查找好友、好友邀请链接功能都使用了 nickname
字段。
通过 TapTap OAuth 授权结果直接登录这一方式创建的玩家,SDK 会自动将 nickname
字段设置为 TapTap 账户的用户名。
用户的查询
TDSUser
是 LCObject
的子类,所以 LCObject
支持的数据增删改查方式,TDSUser
也都可用。感兴趣的读者可以参考数据存储的开发文档了解更多信息。
不过,为了安全起见,内建账户系统(_User
表)默认关闭了 find
权限,这样每位用户登录后只能查询到自己在 _User
表中的数据,无法查询其他用户的数据。如果需要让其查询其他用户的数据,建议单独创建 一张表来保存这类数据,并开放这张表的 find
查询权限。除此之外,还可以在云引擎里封装用户查询相关的方法。
可以参见 用户对象的安全 来了解 _User
表的一些限制,还可以阅读数据和安全来了解更多 class 级权限设置的方法。
关联用户对象
关联 TDSUser
的方法和 LCObject
是一样的。下面的代码为一名作者保存了一本书,然后获取所有该作者写的书:
- Unity
- Android
- iOS
- UE4
LCObject book = new LCObject("Book");
TDSUser author = await LCUser.GetCurrent();
book["title"] = "我的第五本书";
book["author"] = author;
await book.Save();
LCQuery<LCObject> query = new LCQuery<LCObject>("Book");
query.WhereEqualTo("author", author);
// books 是包含同一作者所有 Book 对象的数组
ReadOnlyCollection<LCObject> books = await query.Find();