Leo S
Leo S

Reputation: 339

Do not show specific notification React Native

I do not want to show "NEW_MSG" Push Notification type in a specific screen. I coded below code but when I test it I always get a notification. How can I fix it?

  useEffect(() => {
    notificationListener.current = Notifications.addNotificationReceivedListener(
      (notification) => {
        const {
          room_id,
          message_text,
          type,
        } = notification.request.content.data;
      
        
        // I do not want to show NEW_MSG,
         if (type == "NEW_MSG") {
           console.log(notification);
           return;
         }

      }
    );

    return () => {
      // Unsubscribe when component unmmounts
      Notifications.removeNotificationSubscription(
        notificationListener.current
      );
    };
  }, []);

Note: I use Expo Notifications

Upvotes: 3

Views: 1127

Answers (3)

Dzmitry Dranitski
Dzmitry Dranitski

Reputation: 619

Here is my solution - you can check notification data and determine if you want to show it's alert and play alert sound. Here is my code:

    // https://docs.expo.dev/versions/latest/sdk/notifications/#handling-incoming-notifications-when-the-app-is-in-foreground
    Notifications.setNotificationHandler({
      handleNotification: async (notification) => {
        let shouldShow;

        // will not show alert and sound if we already in this chat
        const chatId = notification?.request?.content?.data?.chatId;
        const currentRouteNameIsChat = navigationRef.getCurrentRoute().name === "Chat";
        const currentRouteChatIdIsSame = navigationRef.getCurrentRoute().params?.chatId == chatId;

        if (chatId && currentRouteNameIsChat && currentRouteChatIdIsSame) {
          shouldShow = false;
        } else {
          shouldShow = true;
        }

        return {
          shouldShowAlert: shouldShow,
          shouldPlaySound: shouldShow,
          shouldSetBadge: false,
        };
      },
    });

setNotificationHandler docs: https://docs.expo.dev/versions/latest/sdk/notifications/#setnotificationhandlerhandler-notificationhandler--null-void

Upvotes: 0

Atmas
Atmas

Reputation: 2393

I believe what you want to do is set up a single custom notification handler that refers to a state variable that you can set/unset on your special screen using the useEffect pa ttern you demonstrated above (i.e. the componentDidMount functional useEffect style).

Apologies, I didn't try writing this up myself first so it may need syntactic help. But it would go something like this...

Setup the handler function for your app and use it for handling your notifications

// The function must refer to a state variable that reacts to whether you're on the screen
let notificationHandlerFn = (notification: Notification) => {
  {
    shouldShowAlert: !onMySuperDuperScreen,   // special state variable
    shouldPlaySound: false,
    shouldSetBadge: false,
  }};

// Register the handler to use the function
Notifications.setNotificationHandler({
  handleNotification: notificationHandlerFn
});

Later, on your special screen

   // Use useEffect to control the state variable
useEffect(() => {
    onMySuperDuperScreen = true;

    return () => {
      onMySuperDuperScreen = false;
    };
  }, []);

Take a look at the expo docs here for details. Read in the section is titled "Handling incoming notifications when the app is in foreground".

Upvotes: 2

Jorge Rivera
Jorge Rivera

Reputation: 51

with this class (Android) you can overwrite the expo notification service and to decide show or not an push notification.

import expo.modules.notifications.notifications.JSONNotificationContentBuilder;
import expo.modules.notifications.notifications.interfaces.NotificationsScoper;
import expo.modules.notifications.notifications.model.Notification;
import expo.modules.notifications.notifications.model.NotificationContent;
import expo.modules.notifications.notifications.model.NotificationRequest;
import expo.modules.notifications.notifications.model.triggers.FirebaseNotificationTrigger;
import expo.modules.notifications.notifications.service.NotificationsHelper;
import expo.modules.notifications.tokens.interfaces.FirebaseTokenListener;

public class FirebaseMessageService extends FirebaseMessagingService {

@Override
  public void onCreate() {
    super.onCreate();
}

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    
    try {
        
        JSONObject json = new JSONObject(remoteMessage.getData());
        JSONObject body = new JSONObject(json.getString("body"));
        
        if (body...) {  //HERE YOUR CONDITIONS
            
            //NOT SHOW RETURN:
            return;
            
        }else{
            
            //SHOW EXPO NOTIFICATION
            createNotificationsHelper().notificationReceived(createNotification(remoteMessage));

        }
    }
    catch (Exception e){
        
    }   
}

public void sendRegistrationToServer(String token) {
}

protected NotificationsHelper createNotificationsHelper() {
  return new NotificationsHelper(this, NotificationsScoper.create(this).createReconstructor());
}

protected Notification createNotification(RemoteMessage remoteMessage) {
  String identifier = remoteMessage.getMessageId();
  if (identifier == null) {
    identifier = UUID.randomUUID().toString();
  }
  JSONObject payload = new JSONObject(remoteMessage.getData());
  NotificationContent content = new JSONNotificationContentBuilder(this).setPayload(payload).build();
  NotificationRequest request = createNotificationRequest(identifier, content, new FirebaseNotificationTrigger(remoteMessage));
  return new Notification(request, new Date(remoteMessage.getSentTime()));
}

protected NotificationRequest createNotificationRequest(String identifier, NotificationContent content, FirebaseNotificationTrigger notificationTrigger) {
  return new NotificationRequest(identifier, content, notificationTrigger);
}

}

in your manifest:

<service
    android:name=".FirebaseMessageService"
    android:exported="false">
    <intent-filter android:priority="-1">
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
  </service>

Upvotes: 1

Related Questions