Search code examples
iosreact-nativeexpoexpo-notifications

Expo Push Notifications Service/API - How to directi anonymous user to specific webview screen in app after engaging with Push Notification


Using Expo Push Notification Service, I currently send Push Notification to all users, which are anonymous. The only data I am collecting and writing to a Firebase Database is the "ExponentPushToken" that identifies a unique device for sending notifications using expo's service. I have been sending Push Notification in terminal using the following command:

curl -H "Content-Type: application/json" -X POST "https://exp.host/--/api/v2/push/send" -d '{
  "to": [
    "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
    "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]"
  ],
  "title": "Hello World!",
  "body": "Example text here!!",
  "sound": "default"
}'

Now, I presume this is not the most flexible way to send notifications, but it allowed me to QUICKLY hit the ground running. My goal now, is to be able to send users that interact with (click/press on) a particular push notification when receiving it on their device to a specific "state" (webview of a particular URL) within the app... I have read through most of the documentation, but I believe some of the content is a bit beyond my ability to interpret regarding what is necessary to make this happen (E.g. setting up Listener's, etc). Wondering if anyone can help simplify implementing this for me? Even if its a bit "janky", I am open to anything!


Solution

  • @AleMux answer nudged me in the right direction, but for the sake of specificity here is how one can accomplish the desired outcome posed in the question.

    Using Expo's Push Notification API, you'll want to ensure you have the appropriate listeners in place, which are already referenced in their API Snack/Example (https://docs.expo.dev/versions/latest/sdk/notifications/#api). For simplicity, this is what we need to focus on for this functionality:

    1. Ensure you've you got the API installed/imported:
    import * as Notifications from "expo-notifications";
    
    1. Setup references to handle notifications and notification responses/interactions:
      const [expoPushToken, setExpoPushToken] = useState("");
      const [notification, setNotification] = useState(false);
      const notificationListener = useRef();
      const responseListener = useRef();
    
    1. For this use case, we want the WebView uri to be able modified. See how this is currently working below, for context. The code below presumes you have necessary dependencies installed (ie. WebView):
      const [page, setPage] = useState("");
      const [baseURI] = useState("https://www.google.com");
    //---A bunch of your app code will presumably be here as to what your app will render, but we'll focus in on the specific needs for this WebView---//
    <WebView source={{uri: `${baseURI}/${page}`}} ref={webviewRef}/>
    
    1. Use the listeners shown below, which can be found/copied from the Expo Push Notification API Snack/Example. In this case I want the action to be the same if the end-user interacts with the notification whether app is in foreground, backgrounded, or killed:
        notificationListener.current =
          Notifications.addNotificationReceivedListener((notification) => {
            setNotification(notification);
            const onInteraction = notification.request.content.data.event;
            setPage(onInteraction);
          });
    
        responseListener.current =
          Notifications.addNotificationResponseReceivedListener((response) => {
            console.log(response);
            const onInteraction = response.notification.request.content.data.event;
            setPage(onInteraction);
          });
    
    1. Lastly, in our HTTP POST request (using CURL in this case) we want to pass a "data" field with a JSON Object that the listeners above can act on. The location above is mentioned regarding where the listener can collect the Object. notification.request.content.data.event. In this case the CURL HTTP POST request would look like this to setPage of webview to a page a page within the baseURI domain that is determined by the information sent to the listener above via the information located in the "data" field of the post request. The location data.event referenced above references the object sent like this "data": {"event": "insert page info here"}. Here is a working example of the complete CURL command:
    curl -H "Content-Type: application/json" -X POST "https://exp.host/--/api/v2/push/send" -d '{
      "to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
      "title": "You have new mail messages!",
      "body": "Check them out here in the app by interacting with this notification.",
      "sound": "default",
      "data": {"event": "mail"}
    }'
    

    When the end user interacts with the push notification (ie. presses the badge) the app will open and webview will render ${baseURI}/${page} which in this case, would be https://www.google.com/mail