Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Local Schedule Notification react native

I am new to React Native i'm trying to implement a functionality where the app sends to user everyday at a certain period of dates and times a notifications to remind users to take pills ( times and dates and data are stored in mongodb server so i'll be using axios to fetch them ) can notifications still works if app is closed or in the background ? is it easy to make it work ? Does anyone know of a way to achieve this , is it possible ?

thanks

like image 641
Ahmed Essaadi Avatar asked May 11 '19 17:05

Ahmed Essaadi


People also ask

How do I get push notifications on iOS?

Go to Settings and tap Notifications. Select an app under Notification Style. Under Alerts, choose the alert style that you want. If you turn on Allow Notifications, choose when you want the notifications delivered — immediately or in the scheduled notification summary.


1 Answers

Yes!!! This is possible. You have many options which includes:

1) Use a background-fetch for iOS and HeadlessTask in Android, here is a decent library https://github.com/jamesisaac/react-native-background-task

2) Push notifications from a server to ensure deterministically that the app wakes app (except it having been killed by the OS). In iOS, ensure that you call notification.finish() to avoid being discriminated by the task handler algorithm.

A Simple example for no 1 goes like this (NOT TESTED!!):

import React from 'react'
import { Text } from 'react-native'
import BackgroundTask from 'react-native-background-task'
import { Notifications, Permissions, Constants } from 'expo';

BackgroundTask.define(async () => {

 // if time is 12pm, fire off a request with axios to fetch the pills info
  const response = await fetch('http://pills-server')


    const text = await response.text()

  // Data persisted to AsyncStorage can later be accessed by the foreground app
  await AsyncStorage.setItem('@MyApp:key', text)  

  // Notification configuration object
  const localNotification = {
        title: text,
        body: 'msg',
        data: data,
        ios: {
          sound: true
        }
      }

 // trigger notification, note that on ios if the app is open(in foreground) the notification will not show so you will need to find some ways to handling it which is discribed here https://docs.expo.io/versions/latest/guides/push-notifications

      Notifications
         .presentLocalNotificationAsync(localNotification)
         .catch((err) => {
            console.log(err)
         })


      BackgroundTask.finish()
})

class MyApp extends React.Component {

  async componentDidMount() {
    // allows the app to recieve notifications (permission stuff)
    this.registerForPushNotificationsAsync().then(() => {
      BackgroundTask.schedule()
    });

  }

  registerForPushNotificationsAsync = async () => {

    const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
    if (status !== 'granted') {
      return;
    }
    let deviceToken = await Notifications.getExpoPushTokenAsync()

  }



  render() {
    return <Text>Hello world</Text>
  }
}

For the second one, the idea is somehow the server should have like a cron job that periodically, sends notification to all user devices based on their different timings/date and pills information stored in the database.

N.B for the server side implemention for expo u can use https://github.com/expo/expo-server-sdk-node for node.js projects, other sdks are listed here: https://docs.expo.io/versions/latest/guides/push-notifications/

import React from 'react'; 
import { Notifications, Permissions, Constants } from 'expo';
import { Text, View } from 'react-native'

class App extends React.Component {

  registerForPushNotificationsAsync = async () => {
    const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
    // prevent device from registering more than once
    if (status !== 'granted') {
     return;
    }

    // get unique token of the device that the server can use to push notification to 
    the device
    let deviceToken = await Notifications.getExpoPushTokenAsync();

    // call a method that sends the device token to the server, in which server stores somewhere and uses in the future
    this.props.registerToken({ deviceToken }).then(() => {

     // the listener here, is called whenever a push notification comes from the server or when the user clicks on the notification at the device tray
      this.notificationSubscription = 
         Notifications.addListener(this.handleNotification);
    })
  }

  handleNotification = (notification) => {

    if (notification.origin === 'selected') {
      // The notification was clicked from the tray by the user i.e selected
      // do stuff to handle selection
    } else {
     // The notification originated from the server
      const localNotification = {
        title: notification.title,
        body: notification.message,
        data: data,
        ios: {
          sound: true
        }
      }
      Notifications.presentLocalNotificationAsync(localNotification).catch((err) => {
        console.log(err)
      })
    }

  }

  async componentDidMount() {

    this.registerForPushNotificationsAsync().then(() => {
    });

  }


  render() {
    return (
     <View>
       <Text>Helllo world</Text>
     </View>
    );
  }
}

Please Note that these solutions have not been tested and may contain some bugs, but the general idea remains the same and can be tweaked :).

Hope it helps.

like image 198
Ewomazino Ukah Avatar answered Oct 02 '22 15:10

Ewomazino Ukah