Add custom metadata
You can make your channels, users, and the relationships between them more descriptive by storing additional information about them.
There are three items you can assign metadata to: users, channels, and memberships. Unlike setting dynamic states, metadata properties are stored in PubNub and you can get their values anytime. Let's look at each of them.
Users have four predefined metadata properties, name
, email
, profileURL
, and externalId
. There is also a custom
property that allows your to store any attribute.
The code below adds a name
, an e-mail
, and a custom nickname
properties to provide more information about a user.
User ID / UUID
User ID is also referred to as UUID
/uuid
in some APIs and server responses but holds the value of the userId
parameter you set during initialization.
- JavaScript
- Swift
- Objective-C
- Android
- C#
- Python
- Dart
- Kotlin
pubnub.objects.setUUIDMetadata({
data: {
name: "Thomas Anderson",
email: "t.anderson@pubnub.com",
custom: {
"nickname": "The One"
}
}
});
let userMetadata = PubNubUserMetadataBase(
metadataId: "uuid",
name: "Thomas Anderson",
email: "t.anderson@pubnub.com",
custom: [ "nickname": "The One" ]
)
pubnub.setUserMetadata(userMetadata) { result in
switch result {
case let .success(metadata):
print("The metadata for `\(metadata.metadataId)`: \(metadata)")
case let .failure(error):
print("Request failed with error: \(error.localizedDescription)")
}
}
self.client.objects().setUUIDMetadata()
.uuid(@"uuid")
.name(@"Thomas Anderson")
.custom(@{ @"nickname": @("The One") })
.email(@"t.anderson@pubnub.com")
.includeFields(PNUUIDCustomField)
.performWithCompletion(^(PNSetUUIDMetadataStatus *status) {
if (!status.isError) {
/**
* UUID metadata successfully has been set.
* UUID metadata information available here: status.data.metadata
*/
} else {
/**
* Handle UUID metadata set error. Check 'category' property to find out possible issue
show all 21 linesMap<String, Object> custom = new HashMap<>();
custom.put("nickname", "The One");
pubnub.setUUIDMetadata()
.name("Thomas Anderson")
.email("t.anderson@pubnub.com")
.custom(custom)
.includeCustom(true)
.async(result -> { /* check result */ });
PNResult<PNSetUuidMetadataResult> setUuidMetadataResponse = await pubnub.SetUuidMetadata()
.Uuid(config.Uuid)
.Name("Thomas Anderson")
.Email("t.anderson@pubnub.com")
.Custom(new Dictionary<string, object>() { { "nickname", "The One" } })
.ExecuteAsync();
PNSetUuidMetadataResult setUuidMetadataResult = setUuidMetadataResponse.Result;
PNStatus status = setUuidMetadataResponse.Status;
pubnub.set_uuid_metadata().uuid(this_uuid) \
.set_name("Thomas Anderson") \
.email("t.anderson@pubnub.com") \
.custom({"nickname": "The One"}) \
.include_custom(True) \
.sync()
var uuidMetadataInput = UuidMetadataInput(
name: 'Thomas Anderson',
email: 't.anderson@pubnub.com',
custom: {'nickname': 'The One'});
var result = await pubnub.objects.setUUIDMetadata(uuidMetadataInput);
pubnub.setUUIDMetadata(
uuid = "unique uuid",
includeCustom = true,
name = "Thomas Anderson",
email = "t.anderson@pubnub.com",
custom = "nickname = The One",
).async { result, status ->
if (status.error) {
//handle error
} else if (result != null) {
//handle result
}
}
Channels have two predefined metadata properties, name
and description
, and a custom
property that allows your to store any attribute.
The code below adds all three properties to provide more information about a channel. This way you're keeping all channel information in one place and can easily present additional data in your app's user interface.
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
- Dart
- Kotlin
pubnub.objects.setChannelMetadata({
channel: "chats_guilds.mages_guild",
data: {
name: "Mages guild",
description: "Mages guild official chatroom.",
custom: { "administrator": "thomas_anderson" }
}
});
let channelMetadata = PubNubChannelMetadataBase(
metadataId: "chats_guilds.mages_guild",
name: "Mages guild",
channelDescription: "Mages guild official chatroom.",
custom: [ "administrator": "thomas_anderson" ]
)
pubnub.set(channel: channelMetadata) { result in
switch result {
case let .success(metadata):
print("The metadata for `\(metadata.metadataId)`: \(metadata)")
case let .failure(error):
print("Request failed with error: \(error.localizedDescription)")
}
show all 16 linesself.client.objects().setChannelMetadata(@"chats_guilds.mages_guild")
.name(@"Mages guild")
.information(@"Mages guild official chatroom.")
.custom(@{ @"administrator": @"thomas_anderson" })
.includeFields(PNChannelCustomField)
.performWithCompletion(^(PNSetChannelMetadataStatus *status) {
if (!status.isError) {
/**
* Channel metadata successfully has been set.
* Channel metadata information available here: status.data.metadata
*/
} else {
/**
* Handle channel metadata update error. Check 'category' property to find out possible
* issue because of which request did fail.
show all 20 linesMap<String, Object> custom = new HashMap<>();
custom.put("administrator", "thomas_anderson");
pubnub.setChannelMetadata()
.channel("chats_guilds.mages_guild")
.name("Mages guild")
.description("Mages guild official chatroom.")
.custom(custom)
.includeCustom(true)
.async(result -> { /* check result */ });
PNResult<PNSetChannelMetadataResult> setChannelMetadataResponse = await pubnub.SetChannelMetadata()
.Channel("chats_guilds.mages_guild")
.Name("Mages guild")
.Description("Mages guild official chatroom.")
.Custom(new Dictionary<string, object>() { { "administrator", "thomas_anderson" } })
.IncludeCustom(true)
.ExecuteAsync();
PNSetChannelMetadataResult setChannelMetadataResult = setChannelMetadataResponse.Result;
PNStatus status = setChannelMetadataResponse.Status;
pubnub.set_channel_metadata().channel("chats_guilds.mages_guild") \
.set_name("Mages guild") \
.description("Mages guild official chatroom.") \
.custom({"administrator": "thomas_anderson" }) \
.include_custom(True) \
.sync()
var channelMetadataInput = ChannelMetadataInput(
name: 'chats_guilds.mages_guild', description: 'Mages guild official chatroom.', custom: { 'administrator': 'thomas_anderson'});
var result = await pubnub.objects
.setChannelMetadata('my_channel', channelMetadataInput);
pubnub.setChannelMetadata(
channel = "chats_guilds.mages_guild",
includeCustom = true,
description = "Mages guild official chatroom",
custom = "administrator thomas_anderson"
).async { result, status ->
if (status.error) {
//handle error
} else if (result != null) {
//handle result
}
}
Memberships are relations between users and channels. You can use membership metadata to, for example, display channel memberships lists for a user or give them the possibility to join or leave channels at their discretion.
Memberships have no predefined metadata properties, as the membership relation is metadata in itself.
The code below adds the current user to the chats_guilds.mages_guild
and chats_inbox.user_1905
channels and adds the friendlist
metadata to the newly created chats_inbox.user_1905
membership.
- JavaScript
- Swift
- Objective-C
- Android
- C#
- Python
- Dart
- Kotlin
pubnub.objects.setMemberships({
channels: [
"chats_guilds.mages_guild",
{id: "chats_inbox.user_1905", custom: {friendlist: true}
}]
});
let channels = [
PubNubMembershipMetadataBase(userMetadataId: "uuid", channelMetadataId: "chats_guilds.mages_guild"),
PubNubMembershipMetadataBase(userMetadataId: "uuid", channelMetadataId: "chats_inbox.user_1905", custom: [ "friendlist": true ]),
]
pubnub.setMemberships(uuid: "uuid", channels: channels) { result in
switch result {
case let .success((memberships, _)):
print("Memberships: \(metadata)")
case let .failure(error):
print("Request failed with error: \(error.localizedDescription)")
}
}
NSArray<NSDictionary *> *channels = @[
@{ @"channel": @"chats_guilds.mages_guild" },
@{ @"channel": @"chats_inbox.user_1905", @"custom": @{ @"friendlist": @YES } }
];
self.client.objects().setMemberships()
.uuid(@"uuid")
.channels(channels)
.includeCount(YES)
.limit(40)
.includeFields(NMembershipCustomField | PNMembershipChannelField)
.performWithCompletion(^(PNManageMembershipsStatus *status) {
if (!status.isError) {
/**
* UUID's memberships successfully set.
show all 30 linesMap<String, Object> custom = new HashMap<>();
custom.put("friendlist", true);
pubnub.setMemberships()
.channelMemberships(Arrays.asList(PNChannelMembership.channel("chats_guilds.mages_guild"), PNChannelMembership.channelWithCustom("chats_inbox.user_1905", custom)))
.async(result -> { /* check result */ });
List<PNMembership> setMembershipChannelMetadataIdList = new List<PNMembership>();
if (!string.IsNullOrEmpty(seMembershipChannelMetaId))
{
setMembershipChannelMetadataIdList.Add(new PNMembership() { Channel = "chats_guilds.mages_guild" });
setMembershipChannelMetadataIdList.Add(new PNMembership() { Channel = "chats_inbox.user_1905", Custom = new Dictionary<string, object>() { { "friendlist", true } } });
}
PNResult<PNMembershipsResult> setMembershipsResponse = await pubnub.SetMemberships()
.Uuid("my-uuid")
.Channels(setMembershipChannelMetadataIdList)
.Include(new PNMembershipField[] { PNMembershipField.CUSTOM, PNMembershipField.CHANNEL, PNMembershipField.CHANNEL_CUSTOM })
.IncludeCount(true)
.ExecuteAsync();
PNMembershipsResult setMembershipsResult = setMembershipsResponse.Result;
PNStatus status = setMembershipsResponse.Status;
pubnub.set_memberships().uuid(this_uuid).channel_memberships([
PNChannelMembership.channel("chats_guilds.mages_guild"),
PNChannelMembership.channel_with_custom("chats_inbox.user_1905", {"friendlist": True})
])
.include_custom(True)
.sync()
var setMetadata = [
MembershipMetadataInput('chats_inbox.user_1905', custom: {'friendlist': 'true'}),
MembershipMetadataInput('chats_guilds.mages_guild ')
];
var result = await pubnub.objects
.setMemberships(setMetadata, includeChannelFields: true);
val custom: MutableMap<String, Any> = HashMap()
custom["friendlist"] = true
pubnub.setMemberships(listOf(
PNChannelWithCustom(channel = "chats_guilds.mages_guild"),
PNChannelWithCustom(channel = "chats_inbox.user_1905", custom = custom))
).async { result, status ->
if (status.error) {
//handle error
} else if (result != null) {
//handle result
}
}
Sometimes you have to limit or grant additional privileges to certain users. This is where our access manager comes in handy.