Search code examples
react-nativeexporeact-native-push-notification

Determine when to send push notifications on expo with HTTP/2 API


I am trying to build a water reminder app. I have 3 screens and I am using react-navigation

  • Home (that I allow users to increase their amount drink that day)
  • Notifications (where users defining with switch buttons if they want to receive notifications and when to receive)
  • Settings (where user enters age, weight to determine how much they should drink daily). this is the first screen users see when they downloaded the app

I am trying to send a push notifications to my users with using expo push notifications and their HTTP/2 API. But I am kinda lost on this and have those questions below.

  1. Where to write push notifications code below and call HTTP/2 API? (App.js, notifications or settings?)
  2. How can I determine when to send this notifications such as for every hour based on users selection.

My code for getting permission, store key and call api to send notifications.

    registerforPushNotifications = async () => {
    // check fox existing permission
    const { status } = await Permissions.getAsync(Permissions.NOTIFICATIONS);
    let finalStatus = status;

    // if no existing permission granted ask user
    if (status !== 'granted') {
      const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
      finalStatus = status;
    }

    //if no permission is granted exit the status
    if (finalStatus !== 'granted') {
      return;
    }

    // get the token
    let token = await Notifications.getExpoPushTokenAsync();

    const request = {
      to: token,
      title: "Don't forget to drink water",
    };

    _storeToken = async () => {
      try {
        await AsyncStorage.setItem('token', token.toString());
      } catch (error) {
        console.log(error.message);
      }
    };

    _storeToken();

    return fetch('https://exp.host/--/api/v2/push/send', {
      method: 'POST',
      headers: {
        'host':'exp.host',
        'accept': 'application/json',
        'content-Type': 'application/json',
        'accept-encoding': 'gzip, deflate'
      },
      body: JSON.stringify(request),
    }).then(data => {console.log(data)});
  };

response that I receive

"_bodyInit": "{\"data\":{\"status\":\"ok\",\"id\":\"93d0f654-d8f6-4587-b4bb-ed4f5cd08b68\"}}",

Solution

  • Instead of using firebase, I have decided to use

    Notifications.scheduleLocalNotificationAsync(localNotification, schedulingOptions)

    This helps me to schedule a local notification to fire at some specific time in the future or at a given interval.

    Arguments

    localNotification (object) -- An object with the properties described in LocalNotification.

    schedulingOptions (object) -- An object that describes when the notification should fire.

    • time (date or number) -- A Date object representing when to fire the notification or a number in Unix epoch time. Example: (new Date()).getTime() + 1000 is one second from now.

    • repeat (optional) (string) -- 'minute', 'hour', 'day', 'week',
      'month', or 'year'.

    • (Android only) intervalMs (optional) (number) -- Repeat interval in
      number of milliseconds

      componentDidMount() { this.willFocusSubscription = this.props.navigation.addListener('willFocus', payload => {

        // call the functions after component did mounted
        this._handleLocalNotification();
        this.listenForNotifications();
      });}
      
      // function to request permission to send notifications and schedule notifications
      _handleLocalNotification = async () => {
      // check fox existing permission
      const { status } = await Permissions.getAsync(Permissions.NOTIFICATIONS);
      let finalStatus = status;
      
      // if no existing permission granted ask user
      if (status !== 'granted') {
        const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
        finalStatus = status;
      }
      
      //if no permission is granted exit the status
      if (finalStatus !== 'granted') {
        return;
      }
      
      const localnotification = {
        title: 'Water Reminder',
        body: 'Dont forget to drink water!',
        android: {
          sound: true,
        },
        ios: {
          sound: true,
        },
      };
      let sendAfterFiveSeconds = Date.now();
      sendAfterFiveSeconds += 5000;
      
      const schedulingOptions = { time: sendAfterFiveSeconds };
      Notifications.scheduleLocalNotificationAsync(localnotification, schedulingOptions);
        };
      

      // function to listen if notification received while the app is open. When it receive, it will create and alert

          listenForNotifications = () => {
            Notifications.addListener(notification => {
              if (notification.origin === 'received') {
                Alert.alert(localnotification.title, localnotification.body);
              }
            });
          };