# Feeds

## Creating a Feed

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
// Feed with no extra fields, of feed group "user"
let feed = client.feed(group: "user", id: "john")
try await feed.getOrCreate()

// More options
let query = FeedQuery(
    group: "user",
    id: "jack",
    data: .init(
        description: "My personal feed",
        name: "jack",
        visibility: "public"
    )
)
let feed2 = client.feed(for: query)
try await feed.getOrCreate()
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
// Feed with no extra fields, of feed group "user"
const feed = client.feed("user", "jack");
await feed.getOrCreate();
// Subscribe to WebSocket events for state updates
await feed.getOrCreate({ watch: true });

// More options
const feed = client.feed("user", "jack");
await feed.getOrCreate({
  data: {
    description: "My personal feed",
    name: "jack",
    visibility: "public",
  },
});
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
// Feed with no extra fields, of feed group "user"
const feed = client.feeds.feed("user", "jack");
await feed.getOrCreate({
  // The owner of the feed
  user_id: "<user id>",
});

// More options
const feed = client.feeds.feed("user", "jack");
await feed.getOrCreate({
  data: {
    description: "My personal feed",
    name: "jack",
    visibility: "public",
  },
  // The owner of the feed
  user_id: "<user id>",
});
```

</codetabs-item>

<codetabs-item value="go-golang" label="Go">

```go
package main

import (
    "context"
    "log"

    "github.com/GetStream/getstream-go/v3"
)

func main() {
    client, err := getstream.NewClient("<your_api_key>", "<your_api_secret>")
    if err != nil {
        log.Fatal(err)
    }

    ctx := context.Background()

    feedsClient := client.Feeds()

    // Feed with no extra fields, of feed group "user"
    feed := feedsClient.Feed("user", "jack")
    response, err := feed.GetOrCreate(ctx, &getstream.GetOrCreateFeedRequest{
        UserID: getstream.PtrTo("<user id>"),
    })
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Feed created: %+v", response.Data.Feed)

    // More options
    advancedResponse, err := feedsClient.GetOrCreateFeed(ctx, "user", "jack", &getstream.GetOrCreateFeedRequest{
        Data: map[string]interface{}{
            "description": "My personal feed",
            "name":        "jack",
            "visibility":  "public",
        },
        UserID: getstream.PtrTo("<user id>"),
    })
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Advanced feed created: %+v", advancedResponse.Data.Feed)
}
```

</codetabs-item>

</codetabs>

## Reading a Feed

Here is a basic example of how to read a feed:

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
let feed = client.feed(group: "user", id: "john")
try await feed.getOrCreate()
let feedData = feed.state.feed
let activities = feed.state.activities
let members = feed.state.members
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
const feed = client.feed("user", "john");
await feed.getOrCreate({ watch: true });
const currentState = feed.state.getLatestValue();

const visivility = currentState.visibility;
const name = currentState.name;
const description = currentState.description;
const activities = currentState.activities;
const members = currentState.members;

// Or subscribe to state changes
const unsubscribe = feed.state.subscribe((state) => {
  // Called everytime the state changes
  console.log(state);
});

// or if you care only part of the state
const unsubscribe2 = feed.state.subscribeWithSelector(
  (state) => ({
    activities: state.activities,
  }),
  (state, prevState) => {
    console.log(state.activities, prevState?.activities);
  },
);

// Unsubscribe when you no longer want to recieve updates
unsubscribe();
unsubscribe2();
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
const feed = client.feed(group: "user", id: "john")
const response = await feed.getOrCreate({
    user_id: '<user id>'
})

const feedData = response.feed;
const activities = response.activities;
const members = response.members;
```

</codetabs-item>

<codetabs-item value="go-golang" label="Go">

```go
package main

import (
    "context"
    "log"

    "github.com/GetStream/getstream-go/v3"
)

func main() {
    client, err := getstream.NewClient("<your_api_key>", "<your_api_secret>")
    if err != nil {
        log.Fatal(err)
    }

    ctx := context.Background()

    feedsClient := client.Feeds()

    // Read a feed
    feed := feedsClient.Feed("user", "john")
    response, err := feed.GetOrCreate(ctx, &getstream.GetOrCreateFeedRequest{
        UserID: getstream.PtrTo("<user id>"),
    })
    if err != nil {
        log.Fatal(err)
    }

    feedData := response.Data.Feed
    activities := response.Data.Activities
    members := response.Data.Members

    log.Printf("Feed data: %+v", feedData)
    log.Printf("Activities: %+v", activities)
    log.Printf("Members: %+v", members)
}
```

</codetabs-item>

</codetabs>

The response will contain the following data.

You have more options when reading a feed, let's go over a few:

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
let query = FeedQuery(
    group: "user",
    id: "john",
    activityFilter: .in(.filterTags, ["green"]), // filter activities with filter tag green
    activityLimit: 10,
    externalRanking: ["user_score": 0.8], // additional data used for ranking
    followerLimit: 10,
    followingLimit: 10,
    memberLimit: 10,
    view: "myview", // overwrite the default ranking or aggregation logic for this feed. good for split testing
    watch: true // receive web-socket events with real-time updates
)
let feed = client.feed(for: query)
try await feed.getOrCreate()
let activities = feed.state.activities
let feedData = feed.state.feed
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
const feed = client.feed("user", "jack");
const response = await feed.getOrCreate({
  limit: 10,
  filter: {
    filter_tags: ["green"], // filter activities with filter tag green
  },
  external_ranking: {
    user_score: 0.8, // additional data used for ranking
  },
  followers_pagination: {
    limit: 10,
  },
  following_pagination: {
    limit: 10,
  },
  member_pagination: {
    limit: 10,
  },
  view: "myview", // overwrite the default ranking or aggregation logic for this feed. good for split testing
});
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
const feed = client.feeds.feed("user", "jack");
const response = await feed.getOrCreate({
  limit: 10,
  filter: {
    filter_tags: ["green"], // filter activities with filter tag green
  },
  external_ranking: {
    user_score: 0.8, // additional data used for ranking
  },
  followers_pagination: {
    limit: 10,
  },
  following_pagination: {
    limit: 10,
  },
  member_pagination: {
    limit: 10,
  },
  view: "myview", // overwrite the default ranking or aggregation logic for this feed. good for split testing
  user_id: "<user id>",
});
```

</codetabs-item>

</codetabs>

### Feed Pagination

Here is how you can read the next page on the feed:

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
let feed = client.feed(
    for: .init(
        group: "user",
        id: "john",
        activityLimit: 10
    )
)
// Page 1
try await feed.getOrCreate()
let activities = feed.state.activities // First 10 activities

// Page 2
let page2Activities = try await feed.queryMoreActivities(limit: 10)

let page1And2Activities = feed.state.activities
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
const feed = client.feed("user", "jack");

// First page
await feed.getOrCreate({
  limit: 10,
});

// Second page
await feed.getNextPage();

console.log(feed.state.getLatestValue().activities);
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
const feed = client.feeds.feed("user", "jack");
const firstPage = await feed.getOrCreate({
  limit: 10,
  user_id: "user_id",
});

const nextPage = await feed.getOrCreate({
  next: firstPage.next,
  limit: 10,
  user_id: "user_id",
});
```

</codetabs-item>

</codetabs>

### Filtering Examples

Another common use case is filtering a feed. This is trickier than it seems. Keep in mind that for performance reasons feeds often have to be computed on write time. To allow for filtering we expose the following API.

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
// Add a few activities
let fid = FeedId(group: "user", id: "john")
try await client.upsertActivities([
    ActivityRequest(fids: [fid.rawValue], filterTags: ["green", "blue"], text: "first", type: "post"),
    ActivityRequest(fids: [fid.rawValue], filterTags: ["yellow", "blue"], text: "second", type: "post"),
    ActivityRequest(fids: [fid.rawValue], filterTags: ["orange"], text: "third", type: "post"),
])
// Now read the feed, this will fetch activity 1 and 2
let query = FeedQuery(fid: fid, activityFilter: .in(.filterTags, value: ["blue"]))
let feed = client.feed(for: query)
try await feed.getOrCreate()
let activities = feed.state.activities // contains first and second
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
const feed = client.feed("user", "123");
// Add a few activities
client.upsertActivities({
  activities: [
    {
      fids: [feed.fid],
      type: "post",
      text: "first",
      filter_tags: ["green", "blue"],
    },
    {
      fids: [feed.fid],
      type: "post",
      text: "second",
      filter_tags: ["yellow", "blue"],
    },
    {
      fids: [feed.fid],
      type: "post",
      text: "third",
      filter_tags: ["orange"],
    },
  ],
});

const response = await feed.getOrCreate({
  filter: {
    filter_tags: ["blue"],
  },
});
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
const feed = client.feeds.feed("user", "123");
// Add a few activities
client.feeds.upsertActivities({
  activities: [
    {
      fids: [feed.fid],
      type: "post",
      text: "first",
      filter_tags: ["green", "blue"],
      user_id: "<user id>",
    },
    {
      fids: [feed.fid],
      type: "post",
      text: "second",
      filter_tags: ["yellow", "blue"],
      user_id: "<user id>",
    },
    {
      fids: [feed.fid],
      type: "post",
      text: "third",
      filter_tags: ["orange"],
      user_id: "<user id>",
    },
  ],
});

const response = await feed.getOrCreate({
  filter: {
    filter_tags: ["blue"],
  },
  user_id: "<user id>",
});
```

</codetabs-item>

</codetabs>

The filter syntax also supports `$or` and `$and`, so here's an example that's a little more complicated:

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
// Get all the activities where tags contain "green" and type is "post" or tag contains "orange" and type is "activity"
let query = FeedQuery(
    group: "user",
    id: "john",
    activityFilter: .or([
        .and([
            .in(.filterTags, ["green"]),
            .equal(.type, "post"),
        ]),
        .and([
            .in(.filterTags, ["orange"]),
            .equal(.type, "activity")
        ])
    ])
)
try await feed.getOrCreate()
let activities = feed.state.activities
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
// Get all the activities where tags contain "green" and type is "post" or tag contains "orange" and type is "activity"
const response = await feed.getOrCreate({
  filter: {
    $or: [
      {
        $and: [{ filter_tags: ["green"] }, { type: "post" }],
      },
      {
        $and: [{ filter_tags: ["orange"] }, { type: "activity" }],
      },
    ],
  },
});
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
// Get all the activities where tags contain "green" and type is "post" or tag contains "orange" and type is "activity"
const response = await feed.getOrCreate({
  filter: {
    $or: [
      {
        $and: [{ filter_tags: ["green"] }, { type: "post" }],
      },
      {
        $and: [{ filter_tags: ["orange"] }, { type: "activity" }],
      },
    ],
  },
  user_id: "<user id>",
});
```

</codetabs-item>

</codetabs>

## Feed Members

You can add and remove members to a feed. This is useful for building communities where a set of users can add content to the feed.

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
// The following methods are available to edit the members of a feed
try await feed.updateFeedMembers(
    request: .init(
        members: [.init(
            custom: ["joined": "2024-01-01"],
            role: "moderator",
            userId: "john"
        )],
        operation: .upsert
    )
)
// Remove members
try await feed.updateFeedMembers(
    request: .init(
        members: [.init(userId: "john"), .init(userId: "jane")],
        operation: .remove
    )
)
// Set members (overwrites the list)
try await feed.updateFeedMembers(
    request: .init(
        members: [.init(role: "moderator", userId: "john")],
        operation: .set
    )
)
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
// The following methods are available to add or edit the members of a feed
await feed.updateFeedMembers({
  operation: "upsert",
  members: [
    {
      user_id: "john",
      role: "moderator",
      custom: {
        joined: "2024-01-01",
      },
    },
  ],
});

// Remove members
await feed.updateFeedMembers({
  operation: "remove",
  members: [
    {
      user_id: "john",
    },
    {
      user_id: "jane",
    },
  ],
});

// Set members (overwrites the list)
await feed.updateFeedMembers({
  operation: "set",
  members: [
    {
      user_id: "john",
      role: "moderator",
    },
  ],
});
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
// The following methods are available to add or edit the members of a feed
await feed.updateFeedMembers({
  operation: "upsert",
  members: [
    {
      user_id: "john",
      role: "moderator",
      custom: {
        joined: "2024-01-01",
      },
    },
  ],
});

// Remove members
await feed.updateFeedMembers({
  operation: "remove",
  members: [
    {
      user_id: "john",
    },
    {
      user_id: "jane",
    },
  ],
});

// Set members (overwrites the list)
await feed.updateFeedMembers({
  operation: "set",
  members: [
    {
      user_id: "john",
      role: "moderator",
    },
  ],
});
```

</codetabs-item>

</codetabs>

## Member invites

You can invite members with the `invite` flag, where invited users can accept or reject the membership.

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
// Request to become a member
try await feed.updateFeedMembers(
    request: .init(
        members: [.init(
            custom: ["reason": "community builder"],
            invite: true,
            role: "moderator",
            userId: "john"
        )],
        operation: .upsert
    )
)
// Accept and reject member requests
_ = try await feed.acceptFeedMember()
_ = try await feed.rejectFeedMember()
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
await invitingFeed.updateFeedMembers({
  operation: "upsert",
  members: [
    {
      user_id: "john",
      role: "moderator",
      invite: true,
      custom: {
        reason: "community builder",
      },
    },
  ],
});

const feed = johnClient.feed(invitingFeed.group, invitingFeed.id);
// Then John can accept or reject
await feed.acceptFeedMemberInvite();

await feed.rejectFeedMemberInvite();
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
await feed.updateFeedMembers({
  operation: "upsert",
  members: [
    {
      user_id: "john",
      role: "moderator",
      invite: true,
      custom: {
        reason: "community builder",
      },
    },
  ],
});

await feed.acceptFeedMemberInvite({
  user_id: "john",
});

await feed.rejectFeedMemberInvite({
  user_id: "john",
});
```

</codetabs-item>

</codetabs>

## Query Feeds

Querying feeds allows you to do things like showing the list of communities you've joined.

Here's an example of how to query feeds:

### Querying My Feeds

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
let query = FeedsQuery(
    filter: .equal(.createdById, "john"),
    sort: [Sort(field: .createdAt, direction: .reverse)],
    limit: 10,
    watch: true
)
let feedList = client.feedList(for: query)
// Page 1
let page1 = try await feedList.get()

// Page 2
let page2 = try await feedList.queryMoreFeeds(limit: 10)

let page1And2 = feedList.state.feeds
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
const firstPage = await client.queryFeeds({
  filter: {
    created_by_id: "john",
  },
  limit: 10,
  sort: [{ field: "created_at", direction: -1 }],
});

const secondPage = await client.queryFeeds({
  filter: {
    created_by_id: "john",
  },
  limit: 10,
  sort: [{ field: "created_at", direction: -1 }],
  next: firstPage.next,
});
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
const firstPage = await client.feeds.feedsQueryFeeds({
  filter: {
    created_by_id: "john",
  },
  limit: 10,
  sort: [{ field: "created_at", direction: -1 }],
});

const secondPage = await client.feeds.feedsQueryFeeds({
  filter: {
    created_by_id: "john",
  },
  limit: 10,
  sort: [{ field: "created_at", direction: -1 }],
  next: firstPage.next,
});
```

</codetabs-item>

</codetabs>

### Querying Feeds Where I Am a Member

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
let query = FeedsQuery(
    filter: .contains(.members, "john")
)
let feedList = client.feedList(for: query)
let feeds = try await feedList.get()
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
await client.queryFeeds({
  filter: {
    members: { $in: ["john"] },
  },
});
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```js
await client.feeds.feedsQueryFeeds({
  filter: {
    members: { $in: ["john"] },
  },
});
```

</codetabs-item>

</codetabs>

### Querying feeds by name or description

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
let sportsQuery = FeedsQuery(
    filter: .and([
        .equal(.visibility, "public"),
        .query(.name, "Sports")
    ])
)
let sportsFeedList = client.feedList(for: sportsQuery)
let sportsFeeds = try await sportsFeedList.get()

let techQuery = FeedsQuery(
    filter: .and([
        .equal(.visibility, "public"),
        .autocomplete(.description, "tech")
    ])
)
let techFeedList = client.feedList(for: techQuery)
let techFeeds = try await techFeedList.get()
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```javascript
await client.queryFeeds({
  filter: {
    visibility: { $eq: "public" },
    name: { $q: "Sports" },
  },
});

// search public feeds by description
await client.queryFeeds({
  filter: {
    // Shorthand for the $eq operator
    visibility: "public",
    description: { $autocomplete: "tech" },
  },
});
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```javascript
await client.feeds.feedsQueryFeeds({
  filter: {
    visibility: { $eq: "public" },
    name: { $q: "Sports" },
  },
});

// search public feeds by description
await client.feeds.feedsQueryFeeds({
  filter: {
    // Shorthand for the $eq operator
    visibility: "public",
    description: { $autocomplete: "tech" },
  },
});
```

</codetabs-item>

</codetabs>

### Querying feeds by creator name

<codetabs>

<codetabs-item value="swift" label="Swift">

```swift
let query = FeedsQuery(
    filter: .and([
        .equal(.visibility, "public"),
        .query(.createdByName, "Thompson")
    ])
)
let feedList = client.feedList(for: query)
let feeds = try await feedList.get()
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```javascript
// search public feeds created by users with 'Thompson' in their name
await client.queryFeeds({
  filter: {
    visibility: "public",
    "created_by.name": { $q: "Thompson" },
  },
});
```

</codetabs-item>

<codetabs-item value="nodejs" label="Node">

```javascript
// search public feeds created by users with 'Thompson' in their name
await client.feeds.feedsQueryFeeds({
  filter: {
    visibility: "public",
    "created_by.name": { $q: "Thompson" },
  },
});
```

</codetabs-item>

</codetabs>

### Feeds Queryable Built-in Fields

| name              | type                      | description                               | supported operations                       | example                                               |
| ----------------- | ------------------------- | ----------------------------------------- | ------------------------------------------ | ----------------------------------------------------- |
| `id`              | string or list of strings | The ID of the feed                        | `$in`, `$eq`                               | `{ id: { $in: [ 'abc', 'xyz' ] } }`                   |
| `group_id`        | string or list of strings | The ID of the group this feed belongs to  | `$in`, `$eq`                               | `{ group_id: { $in: [ 'abc', 'xyz' ] } }`             |
| `fid`             | string or list of strings | The fully qualified feed ID (group_id:id) | `$in`, `$eq`                               | `{ fid: { $in: [ 'abc', 'xyz' ] } }`                  |
| `visibility`      | string or list of strings | The visibility setting of the feed        | `$in`, `$eq`                               | `{ visibility: { $eq: 'public' } }`                   |
| `created_by_id`   | string or list of strings | The ID of the user who created the feed   | `$in`, `$eq`                               | `{ created_by_id: { $in: [ 'abc', 'xyz' ] } }`        |
| `created_by.name` | string                    | The name of the user who created the feed | `$eq`, `$q`, `$autocomplete`               | `{ 'created_by.name': { $autocomplete: 'Frank' } }`   |
| `name`            | string                    | The name of the feed                      | `$eq`, `$q`, `$autocomplete`               | `{ name: { $q: 'Sports' } }`                          |
| `description`     | string                    | The description of the feed               | `$eq`, `$q`, `$autocomplete`               | `{ description: { $autocomplete: 'tech' } }`          |
| `member_count`    | number                    | The number of members in this feed        | `$eq`, `$ne`, `$gt`, `$lt`, `$gte`, `$lte` | `{ member_count: { $gt: 100 } }`                      |
| `members`         | list of strings           | The list of members in this feed          | `$in`                                      | `{ members: { $in: [ 'bob', 'alice' ] } }`            |
| `following_count` | number                    | The number of feeds this feed follows     | `$eq`, `$ne`, `$gt`, `$lt`, `$gte`, `$lte` | `{ following_count: { $gt: 100 } }`                   |
| `following_feeds` | list of strings           | The list of feeds this feed follows       | `$in`                                      | `{ following_feeds: { $in: [ 'feed1', 'feed2' ] } }`  |
| `follower_count`  | number                    | The number of followers of this feed      | `$eq`, `$ne`, `$gt`, `$lt`, `$gte`, `$lte` | `{ follower_count: { $gt: 100 } }`                    |
| `created_at`      | string, RFC3339 timestamp | The time the feed was created             | `$eq`, `$gt`, `$lt`, `$gte`, `$lte`        | `{ created_at: { $gte: '2023-12-04T09:30:20.45Z' } }` |
| `updated_at`      | string, RFC3339 timestamp | The time the feed was updated             | `$eq`, `$gt`, `$lt`, `$gte`, `$lte`        | `{ updated_at: { $gte: '2023-12-04T09:30:20.45Z' } }` |

Feeds can be sorted by `created_at`, `updated_at`, `member_count`, `follower_count`, and `following_count`.

Be sure to reach out to support if you need additional query feed capabilities.

---

This page was last updated at 2025-08-15T14:14:10.124Z.

For the most recent version of this documentation, visit [https://getstream.io/activity-feeds/docs/react-native/feeds/](https://getstream.io/activity-feeds/docs/react-native/feeds/).