Developer Relations Engineer, PubNub
IN THIS ARTICLE
    GitHubGitHub

    Full source code repository on GitHub

    Get the Code

    Let’s say we’re building a connected experience app with realtime features, something like chat messaging so users can text each other in-app. We’ve got great channel topology for global, group, and 1-to-1 chats. Chat messages are stored in PubNub History and can be retrieved later using the Storage & Playback API.

    But what about our user and channel data? Where do we store those? Can we make changes to our data later? Looks like we’ll need to buy into some 3rd party database service and create a mutable storage system, because PubNub History provides infinite storage and playback for messages, but not for user information.

    Not anymore!

    At PubNub, we have developed Objects to get your user and chat room data storage resources built easily, in seconds – not weeks.

    PubNub Objects

    Objects allows applications to store and manage long-lived data for users and the channels they use to communicate within PubNub, without having to spin up additional servers. The features of Objects include:

    • Different schemas, like database tables, which are called Users, Spaces, and Memberships.
    • Relate Objects to one another with IDs, like a database table’s foreign key.
    • Long-lived data storage, unlike the PubNub Functions KV Store in which all data has a time-to-live (TTL).
    • Secure CRUD operations so only authorized users can control data changes with the help of PubNub Access Manager.

    PubNub Objects Diagram

    When to use Objects

    Objects is inspired by chat use cases, but its functionality is not limited to chat. Any PubNub app that has unique users or devices can use Objects to manage groups like you would in any database. Unlike a traditional database, though, Objects is a serverless API.

    Let’s say we are building a chat app like Slack. We need to enable users to join group chats. What is a design best-practice for our application to track which users are part of a group chat? How do we update our database when a new user is added to a group chat? Deleted from the group chat? Do we initialize these changes from the client or server side? Objects makes this simple.

    Demo with Objects

    Let’s go over a simple JavaScript demo to get a better understanding of Objects. For this demo, there are four columns that demonstrate the functionality of Objects:

    • create a user
    • create a space
    • add a user to a space
    • get a list of members for a space

    When an operation is completed, like adding a user, the data will be displayed on the screen.

    PubNub Objects Web Tool

    You can play around with the add, remove, and update functionality of Objects using this web browser demo. Here is a link to the Objects JS Demo Tool GitHub Repository.

    You’ll need to put your PubNub Pub/Sub API keys into the JavaScript code (objects.js): all of the Objects that you write will be accessible with your API key set.

    // Init PubNub
    let pubnub = new PubNub({
        publishKey : 'INSERT_PUB_KEY',
        subscribeKey : 'INSERT_SUB_KEY',
        ssl: true
    });

    Open the HTML page in your favorite web browser and put your object data into the input fields. Hitting the Return key will trigger a write to Objects. Clicking the designated remove button will trigger a delete operation for the respective Object type.

    This tutorial has three sections: Adding DataRemoving Data, and Fetching Data.

    Creating Objects

    Before we continue, if you don’t already have them you’ll need to sign up for a PubNub account to get your free API keys.  Use the form below to sign up or log in:

    Once you have your free API keys, replace the publishKey and subscribeKey values in the following initialization code with your keys. This code is from objects.js. This JS file is where the demo code resides:

    let channel = 'objects';
    
    // Init PubNub
    let pubnub = new PubNub({
      publishKey : 'INSERT_PUB_KEY',
      subscribeKey : 'INSERT_SUB_KEY',
      ssl: true
    });
    
    // Subscribe to a channel
    pubnub.subscribe({
      channels: [channel]
    });

    Next, let’s create a user and save their information using Objects.

    Create a User

    When the user inputs their username and presses the Return key, a call to addUserInfo() is made. This is a PubNub JS SDK method that interacts with the API endpoints. Inside this method, a User Object is created by calling createUser(). The two required parameters for this method are the user_id and the user_name. The user_id must be unique, and is typically the user’s UUID. For the purposes of this demo, a random UUID is generated.

    // Add user
    addUserInfo = (e) => {
      // When user presses the 'Enter' key
      if((e.keyCode || e.charCode) === 13){
        // Generate random number for the user id
        let randNum = Math.floor(Math.random() * 50);
        let userId = `${userInput.value}-${randNum}`;
      }
    }

    We then make a call to the method createUser() with the random user ID and user input.

    pubnub.createUser(
      {
        id: userId,
        name: userInput.value
      },
      function(status, response) {
        // Add to the beginning of users array
        users.unshift({
          user_id : userId,
          user_input : userInput.value
        });
    
        // Display on screen
        userBox.innerHTML =  (''+ userId)+ ': ' + (''+ userInput.value) +  '<br>' + userBox.innerHTML;
        userInput.value = '';
    });
    

    Once the user is added to the Object, the user ID and input are added to the front of the array called users. The array is useful for keeping track of the order in which the users were added. The most recent user is deleted when the Remove button is pressed. Also, the user_id is needed to remove a user from an Object. This will be explained further shortly.

    Once a user is created, the user_id and user_name are displayed on the screen.

    Creating a user with PubNub Objects

    Let’s create a Space Object next.

    Create a Shared Communication Space

    Spaces represent things like chat rooms, categories for your IoT devices, or something similar, depending on your use case. The method to create a space object is createSpace(), where the two required parameters are space_id and the space_name. This method resides inside of addSpaceInfo(), which is called when the user inputs a space name and presses the Return key.  Since the space_id must be unique, the string ID is appended to the space_name. If a user tries to create a space that already exists, they will get an error from the API, which is reflected in the UI through an alert.

    // Add space
    addSpaceInfo = (e) => {
      if((e.keyCode || e.charCode) === 13){
        let spaceId = `${spaceInput.value}_id`;
    
        pubnub.createSpace(
          {
            id: spaceId,
            name: spaceInput.value
          },
          function(status, response) {
            if(status.error){
              alert('Error: A space with that name already exists')
              return;
            }
            spaces.unshift({
              space_id : spaceId,
              space_input : spaceInput.value
            });
            spaceBox.innerHTML =  (''+ spaceId)+ ': ' + (''+ spaceInput.value) + '<br>' + spaceBox.innerHTML;
            spaceInput.value = '';
          });
      }
    }
    

    Again, the data is added to the front of the array. The most recently made space is deleted when the Remove button is pressed. In order to delete a space, the space_id is required.

    Once a space is created, the space_id and space_name are displayed on the screen.

    PubNub Objects Space

    Now that we have created the user and space Objects, let’s take a look at how to add a user to a space.

    Add a User to a Space

    To add a user to a space, we call the method joinSpaces() with parameters user_id and spaces. The user_id is the ID of the user to add to the space(s), while spaces is an array of objects containing the space(s) to be joined. The above method is inside of addUserToSpace() and is called when the user inputs a space ID and user ID and presses Return.  We check that neither input field is empty, as well as check that both IDs are valid.

    addUserToSpace = (e) => {
      if((e.keyCode || e.charCode) === 13){
        // Check that both input fields are not empty
        if(memberInputSpacename.value && memberInputUsername.value){
          pubnub.joinSpaces(
            {
            userId: memberInputUsername.value, // Get user
            spaces: [
              {
                id: memberInputSpacename.value // Join to this space
              }
            ]
          },
          function(status, response) {
            if(status.error){
              alert('Error: Check that space-id and user-id is correct')
              return;
            }
            members.unshift({
              'space_id' : memberInputSpacename.value, 
              'user_id' : memberInputUsername.value,
            });
            memberBox.innerHTML =  (''+ memberInputSpacename.value) + ': ' + (''+ memberInputUsername.value) +'<br>' + memberBox.innerHTML;
            memberInputSpacename.value = '';
            memberInputUsername.value = '';  
          });
        } 
        else {
          alert('Enter both space and user field')
        }
      }
    }
    

    We also add the data to an array called members to delete the most recent data. The newly created membership is displayed on the screen with the space_id and the user_id.

    PubNub Objects Member Relationship

    Next let’s take a look at removing data from Objects.

    Remove Data from Objects

    With our demo tool, we can remove data using Objects and a straightforward user interface. Simply enter your record ID, and click the ‘Remove’ button. This will not only remove the data from the screen, but also delete the record from the Objects data store. You can confirm this by removing data with the tool and refreshing the web page. When the page re-loads it fetches all available Object entries. You’ll notice that the records you removed are no longer shown.

    PubNub Objects Remove User Demo Tool

    In the next section, we will cover deleting from Objects, including users, spaces and memberships.

    Delete User Object

    When the we click the ‘Remove’ button, the removeUser() method is called. As mentioned before, it removes only the most recent user in the list. In order to remove the user from Objects, we need the user_id. To get the ID, we do the following operation:

    // Remove user
    removeUser = () =>{
      //get user id from the first element of the array
      let userId = users[0]["user_id"];
    }

    Once we have the user_id, we call the method deleteUser() which removes the user from the Objects data store. The only parameter for this method is the user_id.

    //remove user from user objects
    pubnub.deleteUser(userId, function(status, response) { 
      console.log(response);
    });
    

    The rest of the code for removeUser() is the logic to remove the user from the browser screen.

    // Remove the first element from the users array
    users = users.slice(1);
    userBox.innerHTML = '';
    
    for(let x = users.length - 1; x >= 0; x--){ // start from end of array     
      let userId = users[x]['user_id']; // get user id
      let userValue = users[x]['user_input']; // get user value
      userBox.innerHTML =  (''+userId)+ ': ' + (''+userValue) +  '<br>' + userBox.innerHTML;
    }

    Delete Space Object

    The code for removing a space from Objects is very similar to removing users. The only parameter we need to pass to deleteSpace() is the space_id.

    // Remove space
    removeSpace = () => {
       //get space id from the first element of the array
      let spaceId = spaces[0]['space_id'];
      //remove space from space objects
      pubnub.deleteSpace(spaceId, function(status, response) {
        console.log(response);
      });
    }

    To remove the space from the screen, we do the following:

    // Remove the first element from the spaces array
    spaces = spaces.slice(1);
    spaceBox.innerHTML = '';
    
    for(let x = spaces.length - 1; x >= 0; x--){ // start from end of array
      let spaceId = spaces[x]['space_id'];// get space id
      let spaceValue = spaces[x]['space_input']; // get space value
      spaceBox.innerHTML =  (''+spaceId)+ ': ' + (''+spaceValue) +  '<br>' + spaceBox.innerHTML;
    }

    Remove a User from a Space

    In order to remove a user from a space with Objects, we need two parameters: user_id and spaces. The spaces parameter is a list of spaces from which to remove a user. These are the two required parameters for leaveSpaces().

    // Remove user from a space
    removeFromSpace = () => {
      //get user id from the first element of the array
      let userId = members[0]['user_id'];
      //get space id from the first element of the array
      let spaceId = members[0]['space_id'];
      
      // Remove user from space objects
      pubnub.leaveSpaces(
        {
          userId: userId,
          spaces: [
            spaceId
          ]
        },
        function(status, response) {
        }
      );
    }
    

    For this demo, we are removing the user from one space. Next, below the function(), add the following to update the screen.

    // Remove the first element from the members array
    members = members.slice(1);
    memberBox.innerHTML = '';
    
    for(let x = members.length - 1; x >= 0; x--){ // start from end of array
      let spaceId = members[x]['space_id']; // get space id
      let userId = members[x]['user_id']; // get user id
      memberBox.innerHTML = (''+ spaceId) + ': ' + (''+ userId) + '<br>' + memberBox.innerHTML;
    }

    We have covered two operations for Objects: Create and Delete. The last operation we’ll cover is Get.

    Fetch Data from Objects

    When a developer needs to fetch all records from a database, they use a SQL “select from” statement. Objects enables easy fetch functionality, so we can programmatically modify our user data in all scenarios.

    When our Objects demo web page loads, data is fetched from the API, parsed, and displayed on the screen. This is possible because Objects data is long-lived. Next we will cover how to fetch data from Objects.

    Get Members from a Space

    We can retrieve members from a given space by using the SDK’s getMembers method. You need to provide a JavaScript object with the space ID (required) and a limiting number of members to be retrieved (optional). The second parameter is a callback function that will execute when Objects provides a response.

    pubnub.getMembers({
        spaceId: spaceIdInput.value,
        limit: 10
    },
    function(status, response) {
        // ...
    });

    Get Users Object

    The getUser method is similar. It requires a user ID.

    pubnub.getUser({
            userId: userId
        },
        function(status, response) {
            // ...
        }
    );

    Get Spaces Object

    We can use the getSpaces method to retrieve all spaces within with our API key set.

    pubnub.getSpaces({
        limit: 5
    },
    function(status, response) {
        let spaceData = response.data;
        for (let x = 0; x < spaceData.length; x++) {
            let spaceId = spaceData[x]['id']; // get space id
            let spaceName = spaceData[x]['name']; // get space name
    
            spaces.unshift({ //add to spaces array
                space_id: spaceId,
                space_input: spaceName
            });
    
            // Display on screen
            spaceBox.innerHTML = ('' + spaceId) + ': ' + ('' + spaceName) + '<br>' + spaceBox.innerHTML;
        }
    });

    Get Users Membership Spaces

    If we need to get all of the spaces that a user is a member of, we can use the getMemberships method. We need to provide a user ID to the method.

    pubnub.getMemberships({
        userId: userId
    },
    function(status, response) {
        // Check if the user is a member of a space
        if (response.data.length > 0) {
            let membershipData = response.data;
            for (let x = 0; x < membershipData.length; x++) {
                let spaceNameId = membershipData[x]['id']; // Get userId
    
                members.unshift({ // Add to members array
                    'space_id': spaceNameId,
                    'user_id': userId,
                });
                // Display on screen
                memberBox.innerHTML = ('' + spaceNameId) + ': ' + ('' + userId) + '<br>' + memberBox.innerHTML;
            }
        }
    });

    Running the Objects Demo

    To run the demo yourself, download the code from the GitHub repository. Then insert your free PubNub API keys into the JS code, as described above. Open the HTML file with your favorite web browser and try Objects for yourself!

    Have suggestions or questions about the content of this post? Reach out at devrel@pubnub.com.

    Try PubNub today!

    Build realtime applications that perform reliably and securely, at global scale.
    Try Our APIs
    Try PubNub today!
    More From PubNub