问题
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
回答1:
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.
来源:https://stackoverflow.com/questions/56092937/local-schedule-notification-react-native