Use case · Activity feeds
A social-style activity feed
Friend requests, likes, comments and shares, in the feed your users already know from social apps. Your backend sends a notification when something happens. The feed, the unread badge and read state across devices come with the SDK.
- created by
- your backend
- audience
- one user per event
- shown in
- feed + badge
- sdk
- node · react native
How the notifications get made
Nobody writes these by hand. Each one comes from an event your backend already handles: a friend request, a like, a comment. You add one call next to it.
01 · Your backend, on every event
Send a notification when something happens
Each event becomes a notification for the user it concerns. The user doesn’t need to exist in NotificationStream yet: they see it on their first visit.
A friend request carries its id in data, so the app can answer it. Once it’s answered, anywhere, your backend cancels it, which removes it and its buttons from every device.
Likes arrive in bursts, so a short-delay job sums them up in one notification and cancels the previous summary. An idempotency key per event makes retries safe.
// Someone sends a friend request
export async function onFriendRequest(request, sender) {
const notice = await ns.notifications.create(
{
audience: { type: "users", userIds: [request.toUserId] },
category: "friends",
contents: {
en: { title: "{{data.name}} sent you a friend request" },
de: { title: "{{data.name}} hat dir eine Freundschaftsanfrage geschickt" },
},
imageUrl: sender.avatarUrl,
actionUrl: `acme://people/${sender.id}`,
data: { type: "friend_request", requestId: request.id, name: sender.name },
},
{ idempotencyKey: `friend-request:${request.id}` },
);
await db.friendRequests.update(request.id, { noticeId: notice.id });
}02 · Your app, once
Show the feed, with your own rows where you need them
<NotificationFeed /> is a complete inbox: tabs, pull to refresh, infinite scroll and “Mark all as read”. Ordinary notifications use the built-in row.
For friend requests, renderItem swaps in your own row with Confirm and Delete buttons that call your API. Archiving it hides it right away, and the cancel from your backend catches up on the user’s other devices.
import {
type FeedItem,
NotificationFeed,
NotificationItem,
useNotifications,
} from "@notificationstream/react-native";
export function NotificationsScreen() {
return (
<NotificationFeed
renderItem={(item) =>
item.data?.type === "friend_request" ? (
<FriendRequestRow item={item} />
) : (
<NotificationItem item={item} />
)
}
/>
);
}
function FriendRequestRow({ item }: { item: FeedItem }) {
const { archive } = useNotifications();
const answer = async (accept: boolean) => {
await api.answerFriendRequest(item.data?.requestId, accept); // your API
await archive(item.id); // gone here at once; your backend cancels it everywhere
};
return (
<RequestRow avatar={item.imageUrl} title={item.title} unread={!item.readAt}>
<Button title="Confirm" onPress={() => answer(true)} />
<Button title="Delete" onPress={() => answer(false)} />
</RequestRow>
);
}What your users get
- A badge that means something
- The unseen count covers what arrived since the user last looked, and the unread count what they haven’t opened.
- Read state on every device
- Read on the phone means read on the web. Archive works the same way.
- New activity within seconds
- With realtime, the app hears that the feed changed and refetches it, instead of polling.
- Tabs by kind
- Every notification has a
category, so you can add tabs for friends, likes or comments. - In their own language
- Write each event’s text once per language with
{{data.name}}-style templates. Names are inserted at read time. - Free to send
- Notifications don’t count against your plan, however many events you send. Only the app’s requests do.
Built with
Plan
Sending to users works on every plan. Realtime, templates and multiple languages need Growth or Scale.
More use cases
Product launches
A launch screen for your early adopters
Show a full-screen announcement in your mobile app to users tagged as early adopters, the next time they open it.
Created by Your product team, in the dashboard
Read the use case
Maintenance in progress. Uploads are paused until 02:30 UTC.
ends in 18 minMaintenance & incidents
Maintenance notices that come and go on time
Warn users the day before, show a banner during the window, and take everything back with one cancel.
Created by Your team in the dashboard, or your incident tooling over the API
Read the use case
Build it this week
Start a free trial, drop the SDK into your app and send your first notification from the dashboard.