const aggregation_view = await serverClient.feeds.createFeedView({
view_id: uuidv4(),
// Group by activity type and day
aggregation: { format: '{{ type }}-{{ time.strftime("%Y-%m-%d") }}' },
});
const myNotificationGrpup = await serverClient.feeds.createFeedGroup({
feed_group_id: "myid",
default_view_id: aggregation_view.feed_view.view_id,
// Enable notification tracking
notification: {
track_read: true,
track_seen: true,
},
});
Notification Feeds
Notification feeds let you notify users about relevant interactions, for example
- someone started to follow them
- someone liked their post
- someone left a comment on their post
Creating notification feeds
The built-in notification
feed comes with the necessary configurations, but it’s also possible to create your own notification feed group:
Aggregation format
The built-in notification
feed uses the following aggregation format: "{{ type }}_{{ time.strftime(\"%Y-%m-%d\") }}"
. You can change this syntax by updating the notification
feed group.
You can see all supported fields and syntax for aggregation in the Aggregation guide.
It’s possible to turn off aggregation, but still enable notification tracking. In that case every new activity will increase unread
/unseen
count. When you have aggregation turned on, unread
/unseen
will refer to the number of aggregated groups.
Adding notification activities
The built-in notification
groups can automatically create notifications for the most common interactions (see Built-in notification feed section).
If you want to extend that, or create your own notification feed, you can add notification activities using server-side integration. You can add webhook handlers for the relevant events to create notifications without API calls from your client-side application to your server-side application.
Built-in notification feed
Creating notification activities
The built-in notification
feed allows you to automatically create notification activities.
// Eric follows Jane
await ericTimeline.follow(janeFeed, {
// When true Jane's notification feed will be updated with follow activity
create_notification_activity: true,
});
// Eric comments on Jane's activity
await ericClient.addComment({
comment: "Agree!",
object_id: janeActivity.id,
object_type: "activity",
// When true Jane's notification feed will be updated with comment activity
create_notification_activity: true,
});
// Eric reacts to Jane's activity
await ericClient.addReaction({
activity_id: janeActivity.id,
// When true Jane's notification feed will be updated with reaction activity
type: "like",
create_notification_activity: true,
});
// Eric reacts to a comment posted to Jane's activity by Sara
await ericClient.addCommentReaction({
comment_id: saraComment.id,
type: "like",
// When true Sara's notification feed will be updated with comment reaction activity
create_notification_activity: true,
});
// Eric follows Jane
await serverClient.feeds.follow({
source: ericTimeline.fid,
target: janeFeed.fid,
// When true Jane's notification feed will be updated with follow activity
create_notification_activity: true,
});
// Eric comments on Jane's activity
await serverClient.feeds.addComment({
comment: "Agree!",
object_id: janeActivity.id,
object_type: "activity",
// When true Jane's notification feed will be updated with comment activity
create_notification_activity: true,
user_id: "eric",
});
// Eric reacts to Jane's activity
await serverClient.feeds.addReaction({
activity_id: janeActivity.id,
// When true Jane's notification feed will be updated with reaction activity
type: "like",
create_notification_activity: true,
user_id: "eric",
});
// Eric reacts to a comment posted to Jane's activity by Sara
await serverClient.feeds.addCommentReaction({
comment_id: saraComment.id,
type: "like",
// When true Sara's notification feed will be updated with comment reaction activity
create_notification_activity: true,
user_id: "eric",
});
Reading notification activities
let notificationFeed = client.feed(group: "notification", id: "jane")
let notifications = try await notificationFeed.getOrCreate()
const notificationFeed = client.feed(group: "notification", id: "jane")
// Read notifications
const notifications = (await notificationFeed.getOrCreate({
limit: 20,
})).aggregated_activities;
const notificationFeed = client.feed(group: "notification", id: "jane")
// Read notifications
const notifications = (await notificationFeed.getOrCreate({
limit: 20,
user_id: '<user_id>'
})).aggregated_activities;
This is what Jane’s notification feed looks like after the above interactions (only relevant fields shown):
- Three aggregated activity groups:
comment-2025-08-04
reaction-2025-08-04
follow-2025-08-04
notification_context
has information about the activity/action that triggered the notification- Please note that
notification_context
field is only defined if you’re using the built-innotification
feed andcreate_notification_activity
flag
- Please note that
{
aggregated_activities: [
{
activity_count: 1,
user_count: 1,
group: "comment-2025-08-04",
activities: [
{
type: "comment",
user: {
id: "eric",
name: "Eric",
// other User fields
},
notification_context: {
trigger: {
text: "Eric commented on your activity",
type: "comment",
},
target: {
user_id: "jane",
type: "post",
text: "As earnestly shameless elsewhere defective estimable fulfilled of",
id: "a0668408-0eb9-4906-a1cf-be79f988051d",
},
},
// Other activity fields
},
],
},
{
activity_count: 1,
user_count: 1,
group: "reaction-2025-08-04",
activities: [
{
type: "reaction",
user: {
id: "eric",
name: "Eric",
},
notification_context: {
target: {
id: "8966090a-30bf-4fe2-b8bc-b0fe36200e56",
user_id: "jane",
type: "post",
text: "Ask too matter formed county wicket oppose talent",
},
trigger: {
type: "reaction",
text: "Eric reacted to your activity",
},
},
},
],
},
{
activity_count: 1,
user_count: 1,
group: "follow-2025-08-04",
activities: [
{
type: "follow",
user: {
id: "eric",
name: "Eric",
},
notification_context: {
target: {
id: "jane",
name: "Jane",
},
trigger: {
type: "follow",
text: "Eric started following you",
},
},
},
],
},
];
}
{
aggregated_activities: [
{
activity_count: 1,
user_count: 1,
group: "comment-2025-08-04",
activities: [
{
type: "comment",
user: {
id: "eric",
name: "Eric",
// other User fields
},
notification_context: {
trigger: {
text: "Eric commented on your activity",
type: "comment",
},
target: {
user_id: "jane",
type: "post",
text: "As earnestly shameless elsewhere defective estimable fulfilled of",
id: "a0668408-0eb9-4906-a1cf-be79f988051d",
},
},
// Other activity fields
},
],
},
{
activity_count: 1,
user_count: 1,
group: "reaction-2025-08-04",
activities: [
{
type: "reaction",
user: {
id: "eric",
name: "Eric",
},
notification_context: {
target: {
id: "8966090a-30bf-4fe2-b8bc-b0fe36200e56",
user_id: "jane",
type: "post",
text: "Ask too matter formed county wicket oppose talent",
},
trigger: {
type: "reaction",
text: "Eric reacted to your activity",
},
},
},
],
},
{
activity_count: 1,
user_count: 1,
group: "follow-2025-08-04",
activities: [
{
type: "follow",
user: {
id: "eric",
name: "Eric",
},
notification_context: {
target: {
id: "jane",
name: "Jane",
},
trigger: {
type: "follow",
text: "Eric started following you",
},
},
},
],
},
];
}
Notification status
If notification tracking is turned on for the feed group then you’ll receive notification status when reading the feed. Notification status tells
- How many unread notifications does the feed have?
- Which notifications are read?
- How many unseen notifications does the feed have?
- Which notifications are seen?
For example, take the notification system on Facebook. If you click the notification icon, all notifications get marked as seen. However, an individual notification only gets marked as read when you click on it.
Here is an example payload for notificaiton status:
{
notification_status: {
// Number of unread notifications
unread: 12,
// Number of unseen notifications
unseen: 0,
last_seen_at: 1754309822808392000,
seen_activities: [],
last_read_at: 1754309822808392000,
read_activities: ['reaction-2025-08-04'],
}
}
// Check if a group is read/seen
const isRead = (lastReadAt && group.updated_at.getTime() < lastReadAt.getTime()) || readActivities.includes(group.group);
const isSeen = (lastSeenAt && group.updated_at.getTime() < lastSeenAt.getTime()) || seenActivities.includes(group.group);
{
notification_status: {
// Number of unread notifications
unread: 12,
// Number of unseen notifications
unseen: 0,
last_seen_at: 1754309822808392000,
seen_activities: [],
last_read_at: 1754309822808392000,
read_activities: ['reaction-2025-08-04'],
}
}
// Check if a group is read/seen
const isRead = (lastReadAt && group.updated_at.getTime() < lastReadAt.getTime()) || readActivities.includes(group.group);
const isSeen = (lastSeenAt && group.updated_at.getTime() < lastSeenAt.getTime()) || seenActivities.includes(group.group);
Marking notifications as seen
await notificationFeed.markActivity({
// Mark all notifications as seen...
mark_all_seen: true,
// ...or only selected ones
mark_seen: [
/* group names to mark as seen */
],
});
await notificationFeed.markActivity({
// Mark all notifications as seen...
mark_all_seen: true,
// ...or only selected ones
mark_seen: [
/* group names to mark as seen */
],
user_id: "<user id>",
});
Marking notifications as read
await notificationFeed.markActivity({
// Mark all notifications as read...
mark_all_read: true,
// ...or only selected ones
mark_read: [
/* group names to mark as read */
],
});
await notificationFeed.markActivity({
// Mark all notifications as read...
mark_all_read: true,
// ...or only selected ones
mark_read: [
/* group names to mark as read */
],
user_id: "<user id>",
});
- I'm working with the Stream Feeds React Native SDK and would like to ask questions about this documentation page: https://getstream.io/activity-feeds/docs/react-native/notification_feeds.md
- View as markdown
- Open in ChatGPT
- Open in Claude