App Context

Showing JavaScript examples.
Starting a new app? Use DataSync

DataSync is the successor to App Context. It does everything App Context does for users, channels, and memberships, and adds typed schemas, partial updates with ETags, field-level access control, and per-class expiry. Refer to How DataSync compares to App Context for a feature-by-feature comparison.

DataSync is currently available to new accounts and to accounts that are not actively using App Context. If your keysets already use App Context, keep using it for now. App Context remains fully supported and these pages stay accurate.

App Context stores structured metadata about the users, channels, and memberships in your application, so you don't run a separate database for profiles, channel descriptions, or channel rosters. You read and write it from an SDK or the REST API directly. No add-on to enable. This page explains:

  • the three entities App Context stores and what each one holds
  • the two directions from which you can read and write a membership
  • how App Context notifies your application in real time when a record changes
  • how to filter App Context data, and how to turn the feature on

One distinction matters throughout: App Context is stored, structured state, not a message and not Presence state. App Context data persists on its own, independent of any single publish or connection, until you change or remove it.

What App Context stores​

App Context has three entity types.

EntityIdentified byBuilt-in fieldsAnswers
User metadataUser IDname, email, externalId, profileUrl, status, typeWho is this user?
Channel metadataChannel namename, description, status, typeWhat is this channel for?
MembershipA User ID and a channel name togetherstatus, type, a last-read timetokenWhich channels does this user belong to?

Every entity also accepts a custom object where you add whatever else your application needs, such as a nickname, an avatar color, or a support-tier flag. Avoid putting personally identifiable information such as an email address or an IP address in a custom field if you plan to map that field into Illuminate for analytics, since Illuminate reads and stores whatever you map into it.

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.

Turn on App Context and configure it​

App Context is a keyset-level feature. Turn it on from your keyset's overview page, alongside the other add-ons described in Set up your account. Once it's on, a handful of options in the Admin Portal decide what App Context stores and shares:

OptionWhat it controls
Bucket RegionWhere PubNub stores your App Context data. Choose a region close to your users to reduce latency. You can't change it after you save it.
User Metadata Events, Channel Metadata Events, Membership EventsWhether a set or delete on that entity type produces the matching real-time event. Each toggles independently.
Disallow Get All Channel Metadata, Disallow Get All User MetadataWhether a valid Access Manager token can call the "get all" operation for that entity type without that operation being listed in the token's own permissions. Leave unchecked to allow it by default.
Enforce referential integrity for membershipsWhether a membership requires its user and channel to already exist, and whether deleting either cascades to delete the membership. See Membership connects users and channels.

Set, read, and remove metadata​

Every App Context entity supports the same four operations:

  • set (which also creates the record on first call)
  • get one
  • get all
  • remove

The following sets a name and a custom field on one user's metadata record, taken from each SDK's own reference sample. Pick your language above:

1

Check the API reference for your platform in Available SDKs documentation.

Every entity type follows the same shape: swap the entity (user, channel, or membership) and the operation (set, get one, get all, or remove) for the equivalent method in your SDK. Every SDK groups these under a dedicated "App Context" or "Objects" section. For the paginated list calls, refer to Get metadata for all users and Get metadata for all channels. For how to receive the event this produces, refer to Real-time updates when metadata changes.

Beyond an SDK, you can manage the same data through the REST API for server-to-server calls, or through BizOps Workspace in the Admin Portal for a no-code UI. User Management and Channel Management create, edit, and delete the same user, channel, and membership records that the SDK and REST calls do. A record you create in one place is visible and editable in the others.

Membership connects users and channels​

A membership is the persistent record that a User ID belongs to a channel. Adding a membership is not the same as subscribing. A membership is a stored relationship your application queries later, and it doesn't by itself deliver any messages. For the full comparison between a stored membership and live Presence, refer to Core concepts.

App Context exposes that one relationship from two directions, and the direction you pick matches how your application already has the data on hand:

  • Memberships operations start from a user. They act on the channels it belongs to, through getMemberships, setMemberships, and removeMemberships. Use this direction to show one user's channel list or to add a user to a handful of channels.
  • Members operations start from a channel. They act on the users that belong to it, through getChannelMembers, setChannelMembers, and removeChannelMembers. Use this direction to show a channel's roster, or to add many users to one channel at once, since setting members is the more efficient path for that kind of bulk write.

Both directions create or remove the same underlying membership record, so a membership set through one direction is immediately visible through the other. For the maximum number of memberships per user and members per channel, refer to What App Context stores.

By default, App Context lets you create a membership for a User ID or channel that doesn't have its own metadata record yet. Deleting a user or channel's metadata also leaves any memberships pointing at it in place. Turning on Enforce referential integrity for memberships in the Admin Portal reverses both behaviors. A membership then requires the user and channel to already exist as their own metadata records, and deleting either one also cascades to delete their memberships.

Real-time updates when metadata changes​

App Context publishes an event every time a set or delete operation succeeds, so a client stays in sync without polling. This event travels through the same subscription and event listener infrastructure as messages and presence, arriving through a dedicated onObjects handler. Its internal message type is 2. For the full payload shape, why it only ever reports set or delete, and how it relates to Events & Actions, refer to App Context events.

Where the event is delivered depends on which entity changed:

  • A channel metadata event publishes on the channel itself, so anyone already subscribed to that channel receives it.
  • A user metadata event publishes on a channel named after that User ID, so a client must subscribe to that User-ID-named channel to receive changes to a user it's watching.
  • A membership event publishes to both: the affected User ID's own channel, and every channel the membership names.

Receiving any of these requires App Context enabled on your keyset, and the matching User Metadata Events, Channel Metadata Events, or Membership Events toggle turned on in the Admin Portal. You can also process these events server-side without a subscribed client, using Functions or Events & Actions.

Filter App Context data​

The "get all" calls, along with getMemberships and getChannelMembers, accept a filter expression. That way, you retrieve only matching records instead of paging through everything and filtering client-side. The language supports comparison operators (==, !=, <, >, <=, >=), logical operators (&&, ||), and SQL-like LIKE pattern matching with * as a wildcard.

Which fields you can filter on depends on which side of the membership relationship you're querying: a memberships call accepts channel.* fields, and a members call accepts uuid.* fields. The two are not interchangeable, so a filter written for one rejects the other's fields.

For applications with many users, channels, or memberships, filter on exact ID equality, such as id == "channel-123", rather than on LIKE pattern matching or a custom field. An exact-match filter on id uses a database index, while a pattern match or a custom field lookup scans every record. This same rule applies to the quick search box versus the Filters button in BizOps Workspace.

Refer to App Context filtering for the complete field list, operators, and syntax.

App Context and access control​

When Access Manager is enabled on your keyset, App Context operations are gated by token permissions on two resource types. User metadata operations (get, update, delete) require a permission grant on that User ID, and channel metadata operations require the same three permissions on the channel. A channel's members and memberships add two more permission bits, manage and join, and setting or removing a membership additionally needs a grant on both the channel and the User ID in the same token. Refer to Set, get, and remove members and Set, get, and remove memberships for the exact permission each operation needs.

A "get all" call is a special case. An App Context "get all" call needs no per-resource permission grant unless you've turned on the matching Disallow Get All option, in which case the token needs an explicit grant for that operation.

Next steps​

Was this page useful?

Last updated on