# Notifications React - Next.js 13 (App router) implementation

**URL:** <https://community.sendbird.com/t/notifications-react-next-js-13-app-router-implementation/8658>\
**Category:** Sendbird Business Messaging\
**Created:** [November 29, 2023, 3:46pm UTC](https://community.sendbird.com/t/notifications-react-next-js-13-app-router-implementation/8658 "2023-11-29T15:46:27Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lorena\_Mrsic](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/lorena_mrsic/32/4723_2.png) [@Lorena\_Mrsic](https://community.sendbird.com/u/Lorena_Mrsic)\
**Post date:** [November 29, 2023, 3:46pm UTC](https://community.sendbird.com/t/notifications-react-next-js-13-app-router-implementation/8658/1 "2023-11-29T15:46:27Z")

</div>

I’m having problems trying to implement Notifications in my Next.js React application.

Problems:

- Notifications sent from Sendbird Dashboard not being received, even though we are connected to sendbird
- Sometimes when we receive a notification templateVariables are empty

I have created a NotificationContext, and a NotificationProvider is wrapped around the whole app. In that Context I’m connecting to sendbird and fetching the Feed channel and doing collection configuration:

```auto
    useEffect(() => {
        const authenticateFeed = async (userId: string, userToken: string) => {
            try {
                const user = await sendbird.connect(userId, userToken);
                setSendbirdUser(user);
            } catch (error) {
                console.log('Error authenticating user', error);
            }
            setIsLoading(false);
        };

        if (data?.user.id && data.token) {
            setIsLoading(true);
            authenticateFeed('3', MOCKED_USER_3_ACCESS_TOKEN);
        }
    }, [data]);

    useEffect(() => {
        const setupNotificationCollection = async () => {
            const filterKeyNumber = FILTER_CATEGORIES[state.filterKey];
            const filter = new MessageFilter();
            filter.customTypesFilter = [`${filterKeyNumber}`];

            const channel = await sendbird.feedChannel.getChannel(
                'notification_50002_feed',
            );
            const collection = channel.createNotificationCollection({ filter });
            collection.setMessageCollectionHandler(messageCollectionHandler);
            collection
                .initialize(
                    MessageCollectionInitPolicy.CACHE_AND_REPLACE_BY_API,
                )
                .onApiResult((err, messages) => {
                    if (messages) {
                        dispatch({
                            type: 'UPDATE_NOTIFICATIONS',
                            payload: messages,
                        });
                    }
                    if (err) console.log('Error', err);
                    setIsLoadingNotifications(false);
                });

            console.log('Notifications initialized.');
        };

        if (sendbirdUser) {
            setIsLoadingNotifications(true);
            setupNotificationCollection();
        }
        // eslint-disable-next-line
    }, [sendbirdUser, state.filterKey]);

```

Sendbird init and messageCollectionHandler is defined here:

```auto
export const sendbird = SendbirdChat.init({
    appId: process.env.NEXT_PUBLIC_SENDBIRD_LOCAL_APP_ID ?? '',
    modules: [new FeedChannelModule(), new GroupChannelModule()],
});

export const messageCollectionHandler: NotificationCollectionEventHandler = {
    onChannelUpdated: (context, channel) => {},
    onMessagesAdded: (context, channel, messages) => {
        console.log('messages: ', messages);
        const newMessages = messages.filter(
            (message) => message.messageStatus === 'SENT',
        );
        if (newMessages.length !== 0) {
            console.log('Messages added', newMessages);
            toast(<ToastNotification message={newMessages[0]} />);
        }
        sendbird.feedChannel.refreshNotificationCollections();
    },
    onMessagesUpdated: (context, channel, messages) => {
        sendbird.feedChannel.refreshNotificationCollections();
    },
    onMessagesDeleted: (context, channel, messageIds, messages) => {
        console.log('Messages deleted', messages);
    },
};

```

The only time that I seem to start getting real time notifications is when I dispatch a change to filterKey, which triggers the useEffect again. But I should be getting the notification before doing that as well…

Am I implementing it wrong? What is a right way to do that so that I can access the notifications through out the whole application if there is a user logged in, and receive real time notifications?

Thanks in advance.

Package versions:  
“@sendbird/chat”: “^4.10.4”,  
“next”: “13.4.11”,  
“next-auth”: “^4.22.3”,  
“react”: “18.2.0”,

---

<div class="post-metadata">

**Author:** ![Tyler](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/tyler/32/810_2.png) [@Tyler](https://community.sendbird.com/u/Tyler)\
**Post date:** [November 30, 2023, 2:21am UTC](https://community.sendbird.com/t/notifications-react-next-js-13-app-router-implementation/8658/3 "2023-11-30T02:21:54Z")

</div>

Hello @Lorena_Mrsic,

Welcome to the Sendbird Community.

I think it’s important to understand that the Sendbird Notifications product is not designed to be realtime. With Notifications, we’ve removed the websocket component to our connection schema and as such it’s designed primarily for use with Mobile platforms because the push notifications act as the “real time” delivery mechanism.

This is why you’re only seeing the new notifications when you’re changing the collection and refetching messages. If you’re looking for new notifications, you could utilize a polling mechanism to see if new notifications exist and then fetch when necessary.

---

<div class="post-metadata">

**Author:** ![Lorena\_Mrsic](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/lorena_mrsic/32/4723_2.png) [@Lorena\_Mrsic](https://community.sendbird.com/u/Lorena_Mrsic)\
**Post date:** [November 30, 2023, 8:57am UTC](https://community.sendbird.com/t/notifications-react-next-js-13-app-router-implementation/8658/4 "2023-11-30T08:57:50Z")

</div>

@Tyler Thank you for your answer.

I see, do you know maybe why do I then get notifications in real time correctly after that?

I don’t need to change filterKey anymore to trigger the useEffect, it only needs to be triggered once after the first render, and then onMessageAdded gets triggered every time I send a new notification?

---

<div class="post-metadata">

**Author:** ![Tyler](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/tyler/32/810_2.png) [@Tyler](https://community.sendbird.com/u/Tyler)\
**Post date:** [November 30, 2023, 11:04pm UTC](https://community.sendbird.com/t/notifications-react-next-js-13-app-router-implementation/8658/5 "2023-11-30T23:04:17Z")

</div>

@Lorena_Mrsic Are you using the UIKit? If so, the UIKit is calling connect underneath which is using realtime connection, thus attributing to your MAU and PCC increases. I think it would be best to get a reproducible sample in something like stackblitz to get a better understanding of your implementation.

---

<div class="post-metadata">

**Author:** ![Lorena\_Mrsic](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/lorena_mrsic/32/4723_2.png) [@Lorena\_Mrsic](https://community.sendbird.com/u/Lorena_Mrsic)\
**Post date:** [November 30, 2023, 11:31pm UTC](https://community.sendbird.com/t/notifications-react-next-js-13-app-router-implementation/8658/6 "2023-11-30T23:31:39Z")

</div>

@Tyler No, I’m only using the Javascript sendbird/chat sdk.  
App will implement UIKit for the Chat functionality in the future though…

I basically described all the code regarding Notifications configuration. Context (with the useEffects in previous code snippets) is wrapped around the app, and I’m using the context in my component:

```auto
export default function Notifications() {
    const { state, dispatch, isLoading, isLoadingNotifications } =
        useNotificationContext();

    const handleFilterChange = (key: TFilterCategorieKey) => {
        dispatch({ type: 'SET_FILTER_KEY', payload: key });
    };

    if (isLoading) return <Loading />;

    return (
        <div className="flex flex-col gap-8">
            <ButtonBack />
            <div className="flex w-full flex-col gap-4">
                <span className=" text-3xl text-opal">Notification center</span>
                <HorizontalLine />
                <div className="flex flex-row gap-3">
                    <Button onClick={() => handleFilterChange('All')}>
                        All
                    </Button>
                    <Button onClick={() => handleFilterChange('Offers')}>
                        Offers
                    </Button>
                </div>
                {isLoadingNotifications && <Loading />}
                {state.notifications.length === 0 && (
                    <div>There are no notifications.</div>
                )}
                {state.notifications.length > 0 &&
                    state.notifications.map((notification) => {
                        return (
                            <div key={notification.id}>
                                <NotificationMessageItem
                                    message={notification}
                                />
                            </div>
                        );
                    })}
            </div>
        </div>
    );
}

```

I currently don’t have time to create reproducible samples, but if I do I will let you know.

But that’s all of the code regarding Notifications implementation anyway, I issued this files on my report to Technical team on the same matter.

---

<div class="post-metadata">

**Author:** ![Tyler](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/tyler/32/810_2.png) [@Tyler](https://community.sendbird.com/u/Tyler)\
**Post date:** [December 1, 2023, 12:00am UTC](https://community.sendbird.com/t/notifications-react-next-js-13-app-router-implementation/8658/7 "2023-12-01T00:00:23Z")

</div>

@Lorena_Mrsic,

The reason I asked is because there is no way for a real time update to have occurred if you’re only using the `authenticateFeed` as it’s only using API calls. There are no websocket events. So either the app is re-rendering causing the data to be refetched or `connect` is being called someone causing you to receive websocket events.

---

<div class="post-metadata">

**Author:** ![Lorena\_Mrsic](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/lorena_mrsic/32/4723_2.png) [@Lorena\_Mrsic](https://community.sendbird.com/u/Lorena_Mrsic)\
**Post date:** [December 1, 2023, 12:21am UTC](https://community.sendbird.com/t/notifications-react-next-js-13-app-router-implementation/8658/8 "2023-12-01T00:21:50Z")

</div>

I would love to have a quick call with you and share my screen to show you whats happening, if that is somehow possible.

---

<div class="post-metadata">

**Author:** ![Tyler](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/tyler/32/810_2.png) [@Tyler](https://community.sendbird.com/u/Tyler)\
**Post date:** [December 1, 2023, 3:15am UTC](https://community.sendbird.com/t/notifications-react-next-js-13-app-router-implementation/8658/9 "2023-12-01T03:15:34Z")

</div>

Unfortunately, I don’t have availability to jump on a call. That being said, I did relook over your code and I do believe I was slightly confused. I see you’re calling `connect` which is generating a websocket connection thus would explain why you’re seeing realtime updates after the first one.

One thing I need to know is when you’re sending the first notification, is it the first notification that user is ever receiving or the first notification the user is receiving after logging into the application.

Please note that `connect()` will cause your MAU and PCC to increase so please be aware of that trade off between using `connect()` and `authenticateFeed()`.

---

<div class="post-metadata">

**Author:** ![Lorena\_Mrsic](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/lorena_mrsic/32/4723_2.png) [@Lorena\_Mrsic](https://community.sendbird.com/u/Lorena_Mrsic)\
**Post date:** [December 4, 2023, 12:11pm UTC](https://community.sendbird.com/t/notifications-react-next-js-13-app-router-implementation/8658/10 "2023-12-04T12:11:57Z")

</div>

It is the first notification that the user is receiving after logging into the application. The previous notifications aren’t shown in onMessageAdded function of the handler, only the ‘new ones’

If we only use authenticateFeed() will we still get the notifications inside collection handler? So in onMessageAdded?

---

<div class="post-metadata">

**Author:** ![Tyler](https://sea2.discourse-cdn.com/flex020/user_avatar/community.sendbird.com/tyler/32/810_2.png) [@Tyler](https://community.sendbird.com/u/Tyler)\
**Post date:** [December 5, 2023, 4:22am UTC](https://community.sendbird.com/t/notifications-react-next-js-13-app-router-implementation/8658/11 "2023-12-05T04:22:33Z")

</div>

@Lorena_Mrsic,

`onMessageAdded` only fires for new events. the `onApiResult` and `onCacheResult` is what loads the previous notifications. I see in your NotificationContext, you’re only building `onApiResult`.

I’ve attempted to reproduce this behavior where you state they’re not getting the first notification after signing in but I’m not able to produce a working reproduction.

One thing you could take a look at is after you’ve initialized the collection and and are connected to the websocket, if you inspect the websocket connection via the dev tools, and then send yourself a new notification you should be able to see whether you’re getting the message over the websocket or not.

* * *

In regards to `authenticateFeed` please note that my goal of pointing this out just to outline the implications of using `connect()` vs `authenticateFeed()` such as MAU and PCC.
