Местное расписание уведомлений реагирует на родное - PullRequest
2 голосов
/ 11 мая 2019

Я новичок в React Native. Я пытаюсь реализовать функциональность, позволяющую приложению ежедневно отправлять пользователю уведомления в определенные периоды времени и даты, чтобы напомнить пользователям о необходимости принимать таблетки (время, даты и данные хранятся в mongodb). сервер, так что я буду использовать Axios, чтобы получить их) могут ли уведомления все еще работать, если приложение закрыто или в фоновом режиме? это легко заставить это работать? Кто-нибудь знает способ достижения этого, возможно ли это?

спасибо

1 Ответ

0 голосов
/ 12 мая 2019

Да !!! Это возможно. У вас есть много вариантов, которые включают в себя:

1) Используйте background-fetch для iOS и HeadlessTask в Android, вот достойная библиотека https://github.com/jamesisaac/react-native-background-task

2) Отправка уведомлений с сервера, чтобы детерминистически убедиться, что приложение запускает приложение (за исключением того, что оно было убито ОС). В iOS убедитесь, что вы вызываете уведомление.finish (), чтобы избежать дискриминации алгоритмом обработчика задач.

Простой пример для no 1 выглядит следующим образом (НЕ ИСПЫТАНО !!):

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>
  }
}

Что касается второго, идея заключается в том, что сервер должен как задание cron, которое периодически отправляет уведомления всем пользовательским устройствам на основе их различных временных параметров / даты и информации о таблетках, хранящихся в базе данных.

N.B для реализации на стороне сервера для выставки вы можете использовать https://github.com/expo/expo-server-sdk-node для проектов node.js, другие sdks перечислены здесь: 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>
    );
  }
}

Обратите внимание, что эти решения не были протестированы и могут содержать некоторые ошибки, но общая идея остается прежней и может быть изменена:).

Надеюсь, это поможет.

...