本地计划通知反应原生

Ahm*_*adi 9 notifications push-notification react-native expo

我是 React Native 的新手我正在尝试实现一个功能,应用程序每天在特定的日期和时间向用户发送通知以提醒用户吃药(时间和日期以及数据存储在 mongodb 服务器中,所以我将使用 axios 来获取它们)如果应用程序关闭或在后台,通知是否仍然有效?让它工作容易吗?有谁知道实现这一目标的方法,有可能吗?

谢谢

Maz*_*kah 5

是的!!!这个有可能。您有很多选择,其中包括:

1)在iOS中使用background-fetch,在Android中使用HeadlessTask,这是一个不错的库 https://github.com/jamesisaac/react-native-background-task

2) 从服务器推送通知,以确保应用程序能够确定地唤醒应用程序(除非它已被操作系统杀死)。在 iOS 中,请确保您调用 notification.finish() 以避免被任务处理程序算法歧视。

一个简单的例子是这样的(未经测试!!):

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>
  }
}
Run Code Online (Sandbox Code Playgroud)

对于第二个,这个想法是服务器应该有一个类似 cron 作业的功能,定期根据所有用户设备的不同时间/日期和存储在数据库中的药丸信息向所有用户设备发送通知。

注意,对于 expo 的服务器端实现,您可以使用https://github.com/expo/expo-server-sdk-node进行 Node.js 项目,其他 sdk 列于此处: https: //docs.expo.io/版本/最新/指南/推送通知/

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>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这些解决方案尚未经过测试,可能包含一些错误,但总体思路保持不变,可以进行调整:)。

希望能帮助到你。