2021年3月30日星期二

Sending push notifications in Expo React Native app to multiple devices at once?

I'm still a newbie to React Native, but I am trying to integrate push notifications to my iOS & Android devices. Most tutorials I have seen with Expo use their website to push a notification using a specific token, but i do not want to do that. I want to send one notification to multiple devices at once (regardless of the OS on the device, aka iOS or Android). I think my best bet is doing it through Firebase, which is what this tutorial does. I also found the GitHub that matches the tutorial, but they use ListView, which is now deprecated. I am getting the error that I cannot use ListView in that Github's code, and when I tried to switch it to a Flatlist, I'm getting an error saying that cloneWithRows is not a function. Can someone help me with that portion of the code? Or if you have alternative resources about how to push a notification to multiple devices let me know please. Edit: I'll post the code below for convenience from the GitHub. All credits go to him. TLDR: Code doesn't work because ListView has been deprecated, and if I change it to FlatList, the cloneWithRows doesn't work. Not sure how to restructure it with a Flatlist, please help if you can.

import React from 'react';  import { StyleSheet, Text, View, StatusBar} from 'react-native';  import { Container, Content, Header, Form, Input, Item, Button, Label, Icon, List } from 'native-base'  import firebase from 'firebase';  import { Permissions, Notifications } from 'expo';  import { FlatList } from 'react-native';  import { ListView } from 'react-native';    var data = []    export default class App extends React.Component {        static navigationOptions = {          header: null      }      constructor(props) {          super(props);          this.ds = new ListView({ rowHasChanged: (r1, r2) => r1 !== r2 })          this.state = {              listViewData: data,              newContact: "",              currentUser: ""          }      }        componentDidMount() {          var currentUser          var that = this          listener = firebase.auth().onAuthStateChanged(function (user) {              if (user != null) {                  currentUser = user                  that.registerForPushNotificationsAsync(currentUser)              }              listener();          });            firebase.database().ref('/contacts').on('child_added', function (data) {              var newData = [...that.state.listViewData]              newData.push(data)              that.setState({ listViewData: newData })          })      }        loadSubscribers = () => {          var messages = []            //return the main promise          return firebase.database().ref('/subscribers').once('value').then(function (snapshot) {              snapshot.forEach(function (childSnapshot) {                    var childKey = childSnapshot.key;                    messages.push({                      "to": childKey,                      "sound": "default",                      "body": "New Note Added"                  });              });              //firebase.database then() respved a single promise that resolves              //once all the messages have been resolved               return Promise.all(messages)            }).catch(error => {              console.log(error)          })        }        registerForPushNotificationsAsync = async (currentUser) => {          const { existingStatus } = await Permissions.getAsync(Permissions.NOTIFICATIONS);          let finalStatus = existingStatus;            // only ask if permissions have not already been determined, because          // iOS won't necessarily prompt the user a second time.          if (existingStatus !== 'granted') {              // Android remote notification permissions are granted during the app              // install, so this will only ask on iOS              const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);              finalStatus = status;          }            // Stop here if the user did not grant permissions          if (finalStatus !== 'granted') {              return;          }            // Get the token that uniquely identifies this device          let token = await Notifications.getExpoPushTokenAsync();            // POST the token to our backend so we can use it to send pushes from there          var updates = {}          updates['/expoToken'] = token          await firebase.database().ref('/users/' + currentUser.uid).update(updates)          //call the push notification       }          addRow(data) {            var key = firebase.database().ref('/contacts').push().key          firebase.database().ref('/contacts').child(key).set({ name: data })      }        async deleteRow(secId, rowId, rowMap, data) {            await firebase.database().ref('contacts/' + data.key).set(null)            rowMap[`${secId}${rowId}`].props.closeRow();          var newData = [...this.state.listViewData];          newData.splice(rowId, 1)          this.setState({ listViewData: newData });        }        render() {          return (              <Container style={styles.container} >                  <Header style=>                      <Content>                          <Item>                              <Input                                  onChangeText={(newContact) => this.setState({ newContact })}                                  placeholder="Add Note"                              />                              <Button onPress={() => this.addRow(this.state.newContact)}>                                  <Icon name="add" />                              </Button>                          </Item>                      </Content>                  </Header>                    <Content>                      <List                          enableEmptySections                          dataSource={this.ds.cloneWithRows(this.state.listViewData)}                          renderRow={data =>                              <ListItem>                                  <Text> {data.val().name}</Text>                              </ListItem>                          }                          renderLeftHiddenRow={data =>                              <Button full onPress={() => this.addRow(data)} >                                  <Icon name="information-circle" />                              </Button>                          }                          renderRightHiddenRow={(data, secId, rowId, rowMap) =>                              <Button full danger onPress={() => this.deleteRow(secId, rowId, rowMap, data)}>                                  <Icon name="trash" />                              </Button>                            }                            leftOpenValue={-75}                          rightOpenValue={-75}                      />                    </Content>              </Container>          );      }  }    const styles = StyleSheet.create({      container: {          flex: 1,          backgroundColor: '#fff',        },  });  
https://stackoverflow.com/questions/66880853/sending-push-notifications-in-expo-react-native-app-to-multiple-devices-at-once March 31, 2021 at 10:30AM

没有评论:

发表评论