This page looks best with JavaScript enabled

How to create social media app with GetStream and Node.JS

 ·  ☕ 7 min read  ·  ✍️ Iskander Samatov

getStream


Social media app can quickly go viral but at the same time it is tremendously difficult to get right. In today’s social media app market users expect your app to have certain features that are hard to implement. Building those features from scratch takes a long time. So in this post I’m showing how you can leverage Stream API to build your social media app components, make the development faster and save yourself weeks, if not months of work.

Have a separate server

Since social media app is bound to be complicated, it’s always a good idea to have a separate back-end server for it. In this tutorial we’re going to use Node.JS and Stream’s JavaScript library to build our back end, but you can choose any language and platform that you wish. Stream has libraries for most of the popular server side frameworks like Java, Go, .NET, Ruby and etc.

What is Stream?

In short, Stream is an API for handling user interactions and activity streams in your social media app. Stream includes free and paid tiers. Paid tier is of course more powerful and feature-rich but their free tier can still help you immensely in building your app.

What Stream is meant to be used as:

  • Provides you with an infrastructure and algorithms to handle feeds, timelines and providing user with a regularly updated and personalized data.
  • Can help you keep track of social interactions(likes, comments, favorites).
  • Helps you keep track of followers and rankings.
  • Helps you provide your users with realtime notifications.

What Stream is not meant to be used as:

  • Stream should not be used as a database. You should have your own database work in tandem with Stream and store most of the user profile and content data in your database.

Users

Users are the building block of any social media app so it’s important to take time to consider the architecture for your user data. However, Stream is not really built to store a whole lot of user data in it. I even suggest not to store any user data in Stream and use your own database for that instead. The only thing you really need to store in Stream is a unique user identifier to tie the users to their posts and reactions. Unique identifier can be anything you choose as long as it’s truly unique(email, username, user hash and etc).

Feeds

Stream provides 3 types of feeds:

  • Flat Feed – Your usual type of feed that stores a content based on user’s activity and following, think Twitter.
  • Aggregate feed – groups activities together, similar to Facebook’s activity feed (Matt and 17 others liked your picture).
  • Notification feed – similar to Aggregated feeds but extends it with a few additional features that make this feed a good candidate to track notifications (seen, opened and etc).

Don’t worry if the difference between the feeds is not very apparent. The main takeaway here is that different feeds are better suited for different purposes. Also, do not think that you can only choose one or the other. You can (and should) have more than one feed in your project, each handling different responsibility.

Activities

Activity is a content item that forms your social media app’s data. Activities can be almost anything like posts or user events and etc. Each activity has three mandatory fields: actor, verb and object. On top of the mandatory fields, activities can also have custom fields. We’ll see an example of posting an activity later in this post.

Reactions

Reaction is a special kind of data that captures user’s interaction with other people’s activities in your social media app. Reactions can be likes, comments, upvotes and etc. Also, reactions are always tied to the specific activity.

When creating a reaction you need to provide four fields: kind, activity_id, data and target feeds. The last field allows you to select specific user feeds that will receive a notification, ex: timeline:iskander.

Notifications

The last type of Stream data that I want to talk about is notifications. The way to create and manage notifications in Stream is by creating a separate Notification Feed. Adding a new notification is just like adding a new activity to the feed.

You can also setup realtime notifications in your social media app by subscribing to feed updates via web-hooks or socket connections. Stream JavaScript library comes with the built-in support for realtime updates via sockets.

Examples

Now that we’re familiar with the building blocks of Stream API let’s take a look at some examples.

Connecting to Stream API

1
const client = stream.connect(STREAM_KEY, STREAM_SECRET, APP_ID);

As you can see, creating a new client instance is easy, all you need to do is provide key, secret and id of your project. You can get all three from your Stream Dashboard.

Following people

In my project I have 3 different feeds with different purposes: user, timeline and notifications.

  • user is for keeping track of the activities created by the user (posts, events).
  • timeline is for displaying the news feed to the user. It stores and displays all the recent activities of the people that user follows.
  • notification is for keeping track of user’s notifications.
1
2
3
4
const followUser = (username, following) => {
  const timelineFeed = client.feed('timeline', username);
  timelineFeed.follow('user', following);
};

In this example username is the username of current user and following is username of the person current user is trying to follow. First we create a new reference instance of the user’s timeline feed and use follow method to follow other person’s user feed. Now every time there’s a new activity in other person’s user feed, that activity will be automatically added to the current user’s timeline feed.

Getting feed activities

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const getTimelineFeed = (username) => {
  const timeLineFeed = client.feed('timeline', username);
  return timeLineFeed.get({
    limit: 25,
    reactions: {
      counts: true,
    },
  }).then((result) => {
    return result;
  });
};

In this example we’re getting all the recent activities in user’s timeline feed. We’re limiting the result to 25 items and making sure to include all the reactions each activity received by specifying reactions: {counts: true}. Here’s what a sample output would look like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[
  {
      "author": "toyjake74737",
      "id": "ELBQLRyUFfTn1BkPxMsm",
      "title": "Creepy Uber",
      "lastUpdated": 1554394376612,
      "favoriteCount": 1
  },
  {
      "author": "toyjake74737",
      "id": "uscJiTLIV2Z6tGCjyXGA",
      "title": "Behind the Bed",
      "lastUpdated": 1554392940780,
      "favoriteCount": 1
  },
]

Adding activity

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const addPostActivity = (username, postId, postTitle, timestamp) => {
  const userFeed = client.feed('user', username);
  return userFeed.addActivity({
    actor: username,
    verb: 'post',
    object: postId,
    foreign_id: `post:${postId}`,
    postTitle,
    timestamp,
  });
}

In this example we’re adding a new post to user’s user timeline as an activity. Important things to note:

  • We’re adding 3 required fields for each activity: actor, verb, object.
  • verb can be any value you choose as long as you’re consistent with it throughout all of your API calls.
  • foreign_id is not required but necessary if you plan on updating your activity in the future. You need to make sure that foreign_id is unique across all of your activities.
  • postTitle and timestamp are additional custom fields that I added to my activity.

Adding activity reactions

1
2
3
4
5
6
7
8
const addReaction = (username, type, postActivityId) => {
  const userClient = getClient();

  return userClient.reactions.add(type, postActivityId, {
    actor: username,
    timestamp: new Date().getTime(),
  });
}

This method is for adding new reactions to the activities. First we instantiate a new client and use reactions.add to add a new reaction. We specify the type of reaction (like, comment) as a string and activity id. The last parameter is my custom data that I’m passing for a later user.

You can easily fetch reactions for the activity:

1
2
3
const reactions = client.reactions.filter({
  'activity_id': postActivityId
});

And that’s it for this post! You can definitely find more explanation and API examples by visiting Stream documentation . Building a social media app is no easy feat, but with the help of Stream API that daunting task seems much more manageable.

Share on

Software Development Tutorials
WRITTEN BY
Iskander Samatov
The best up-to-date tutorials on web and mobile development.