用户属性
Storage
服务为你提供了用户属性的能力,可以用来存储和分发你的应用中关于用户的上下文数据,例如:姓名、年龄、头像连接等一切自定义数据。用户属性在被设置、更新和删除的时候会触发 eventType
事件通知,订阅此用户属性的用户会在 100ms 内收到此信息。
需要注意的是,用户属性属于永久存储,一旦被设置将会长期保存在 RTM 数据库,不会因为你的用户注销而丢失,直到你手动删除它们为止。知道这一点非常重要,因为它将影响你的存储计费项,详见计费规则。
设置用户属性
你可以为指定的用户设置一组用户属性用以实现业务上用户级别的数据存储和实时通知,例如用户的姓名、年级、头像链接、自我介绍等任何自定义数据。每个用户只能有一组用户属性,但每组用户道属性可以包含一个或多个子属性,相关限制详见 API 使用限制。每个子属性包含有 key
、value
、revision
预定义字段。
如果当前用户属性或者子属性不存在,该方法将为指定用户新增属性;如果用户属性或者子属性存在,则会使用新值覆盖原有值。
以下示例代码展示了如何置用户属性:
const Name = {
key : "Name" ,
value : "Tony"
};
const Age = {
key : "Age",
value : "40"
};
const Avatar = {
key : "Avatar",
value : "https://your-domain/avatar/tong.png"
};
const data = [Name, Age, avatar];
const options = { addTimeStamp : true , addUserId : true };
try {
const result = await rtm.storage.setUserMetadata(data, "Tony", options);
console.log(JSON.stringify(result));
} catch (status) {
console.log(JSON.stringify(status));
}
上述示例代码中,我们为用户 Tony
设置了一组用户属性,其中包含三个用户子属性 Name
、Age
和 Avatar
,同时我们设置了 options
参数要求 RTM 服务在存储上述三个子属性时额外添加上时间戳(addTimeStamp
)和修改者(addUserId
)信息。上述代码使用了 await/async
编程模式,需要被定义在一个异步函数中才能正常使用。
关于 setUserMetadata
接口详见 Storage API 参考。
当上述操作成功后,RTM SDK 会返回如下数据结构:
{
timeToken : 18770098911, // 本次操作成功时间戳
userId : "Tony", // 用户名
totalCount : 3 // 用户子属性个数
}
同时, RTM 还会触发一个 UPDATE
类型的 eventType
事件通知,并在 100ms 内通知到订阅此用户属性的用户。eventType
详见事件通知。
获取用户属性
你可以通过调用 getUserMetadata
方法获得指定用户的全部属性数据。以下示例代码展示如何获取用户属性:
try {
const result = await rtm.storage.getUserMetadata("Tony");
console.log(JSON.stringify(result));
} catch (status) {
console.log(JSON.stringify(status));
}
你也可以通过不指定 userId
参数以获取自己的用户属性数据:
try {
const result = await rtm.storage.getUserMetadata();
console.log(JSON.stringify(result));
} catch (status) {
console.log(JSON.stringify(status));
}
当上述操作成功后,RTM SDK 会返回如下数据结构:
{
totalCount: 3,
majorRevision: -1,
metadata:{
"Name":{
value:"Tony",
revision:-1,
updated:"2022-05-20T23:11:20.893755",
authorUid:"Tony"
},
"Age":{
value:"40",
revision:-1,
updated:"2022-05-20T23:11:20.893755",
authorUid:"Tony"
},
"Avatar":{
value:"https://your-domain/avatar/tong.png",
revision:-1,
updated:"2022-05-20T23:11:20.893755",
authorUid:"Tony"
}
},
userId: "channel1",
timeToken: 18770098911
}
更新用户属性
你可以使用 updateUserMetadata
来更新已存在的用户属性。如果该属性不存在,则会返回错误。该接口可用于需要权限控制的业务场景,例如:应用的设置者预定义了用户属性的数据字段和格式,用户只具备更新的权限。
以下示例代码展示了如何更新用户子属性值:
const Age = {
key : "Age",
value : "45"
};
const data = [Age];
const options = { addTimeStamp : true , addUserId : true };
try {
const result = await rtm.storage.updateUserMetadata(data, "Tony", options);
console.log(JSON.stringify(result));
} catch (status) {
console.log(JSON.stringify(status));
}
上述示例代码将 key
为 Age
的年龄数据更新为 45
。当成功后,RTM SDK 会返回如下数据结构:
{
timeToken : "", // 本次操作成功时间戳
userId : "Tony", // 用户名
totalCount : 3 // 用户子属性个数
}
同时, RTM 还会触发一个 UPDATE
类型的 eventType
事件通知,并在 100ms 内通知到订阅此用户属性的其他人。eventType
详见事件通知。
删除用户属性
当你不再需要指定用户的属性或者某几个子属性,你可以进行删除操作。以下示例代码展示了如何使用 removeUserMetadata
删除属性:
const Age = {
key : "Age",
value : ""
};
const data = [Age];
try {
const result = await rtm.storage.removeUserMetadata(data, "Tony");
console.log(JSON.stringify(result));
} catch (status) {
console.log(JSON.stringify(status));
}
以上示例代码中 value
不论为何值都没有影响。
如果 removeUserMetadata
接口中不填写 data
参数,则会删除指定用户的整组用户属性。参照以下示例代码:
try {
const result = await rtm.storage.removeUserMetadata("Tony");
console.log(JSON.stringify(result));
} catch (status) {
console.log(JSON.stringify(status));
}
销毁用户账户的过程中常见删除整组用户属性的操作。用户属性数据一旦被删除将无法恢复,如果你对数据具有恢复的需求,那么你需要谨慎使用该方法并做好数据备份。
同时, RTM 还会触发一个 UPDATE
类型的 eventType
事件通知,并在 100ms 内通知到订阅此用户属性的其他人。eventType
详见事件通知。
订阅用户属性
与订阅频道属性类似,如果你需要关注某个用户的属性更新,那么你可以订阅该用户的用户属性,参照以下示例代码:
try {
const result = await rtm.storage.subscribeUserMetadata("Tony");
console.log(JSON.stringify(result));
} catch (status) {
console.log(JSON.stringify(status));
}
以上示例中我们订阅了用户名为 Tony
的用户属性,当 Tony
的用户属性变化时 RTM 会触发一个 UPDATE
类型的 eventType
事件通知,并在 100 ms 内通知到你。
取消订阅用户属性
如果你对不再关注某个用户的用户属性变更,可以取消订阅,参照以下示例代码:
try {
const result = await rtm.storage.unsubscribeUserMetadata("Tony");
console.log(JSON.stringify(result));
} catch (status) {
console.log(JSON.stringify(status));
}
操作成功后,你将不再会受到此用户属性变更通知。
CAS 控制
用户属性与频道属性相同,也存在 CAS 控制机制。该方法提供两种独立的版本控制字段,你可以跟根据实际业务场景设置任意一种或多种:
- 通过
MetadataOptions
中的majorRevision
属性开启整组用户属性的版本号校验。 - 通过
MetadataItem[]
中的revision
属性开启每个用户子属性的版本号校验。
你可以在需要权限控制的场景中应用 CAS 控制,例如:在交友 APP 中同时只允许一位观众与主播连麦,多人同时发起请求,只有最先操作的人会成功。
以下示例代码展示了如何使用 majorRevision
和 revision
更新用户属性和子属性:
const sessionRequest = {
key : "sessionRequest",
value : "Robbin's session request",
revision : 1000
};
const data = [sessionRequest];
const options = { addTimeStamp : ture , addUserId : ture, majorRevision : 100 };
try {
const result = await rtm.storage.updateUserMetadata(data, "Tony", options);
console.log(JSON.stringify(result));
} catch (status) {
console.log(JSON.stringify(status));
}
上述例子中,我们对频道属性和子属性 properties
和 price
开启 CAS 验证并设置 majorRevision
为 100
。服务器在接收到接口调用请求后,会首先验证接口调用提供的 majorRevision
与数据库最新值是否匹配,如果不匹配,则返回错误;如果匹配,则继续验证子属性的 revision
,逻辑与验证用户属性相同。
如果你开启了版本控制能力,那么你需要关注 eventType
事件通知以获取 majorRevision
和 revision
更新后的值,以便于在接口调用时提供最新值。