Я использую облачные сообщения Firebase в своем собственном приложении. У меня есть обычный класс (не реагирующий компонент) со статическими методами и переменными, который создается при запуске приложения. В этом классе есть три статических метода / слушателя (передний план, фон и приложение запуска) для управления push-уведомлениями из firebase.
Я пытаюсь справиться с действиями, когда на переднем плане.
Как сделать модал поверх экрана (не переключая экраны, а запустить оверлейную карту в центре с двумя кнопками), когда пользователь получает push-сообщение от firebase, независимо от того, на каком экране он работает?
Пробное решение, предоставленное в этой статье на hackernoon, обертывание модального компонента внутри AppContainer ничего не сделало. https://hackernoon.com/managing-react-modals-with-singleton-component-design-5efdd317295b
Я также попробовал идею этого урока с модальным компонентом, но ни в одном случае не преуспел.
https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html
Класс облачных сообщений Firebase:
export default class FCM {
static appClosedListener = async () => {
const firebaseContent = await firebase.notifications().getInitialNotification();
if (firebaseContent) {
console.log(firebaseContent);
const serverParcel = JSON.parse(firebaseContent._data.payload).an;
const notificationState = "closedapp";
FCM.pushNotificationHandler(serverParcel, notificationState);
}
};
static backgroundListener = () => {
FCM.background = firebase.notifications().onNotificationOpened(firebaseContent => {
const serverParcel = JSON.parse(firebaseContent._data.payload).an;
const notificationState = "background";
FCM.pushNotificationHandler(serverParcel, notificationState);
});
};
static foregroundListener = () => {
FCM.foreground = firebase.notifications().onNotification(firebaseContent => {
const serverParcel = JSON.parse(firebaseContent._data.payload).an;
const notificationState = "foreground";
FCM.pushNotificationHandler(serverParcel, notificationState);
});
};
static pushNotificationHandler = (serverParcel, notificationState) => {
const typeOfAction = serverParcel.typeEnum;
switch(typeOfAction){
case "message":
break;
case "webnews":
const url = serverParcel.link;
NavigationService.navigate("FCMModal", {}); //Here is where I want the modal to popup.
//NavigationService.navigate("InAppBrowser", {url});
break;
}
}
App.js
const ModalStack = createStackNavigator(
{
FCMModal: FCMModal
},
{
mode: 'modal',
transparentCard: true,
cardStyle: {
// makes transparentCard work for android
opacity: 1.0
}
}
)
let rootStack = createStackNavigator(
{
main: {
screen: BottomTabNavigator //There are four navigatorstacks with multiple screens beneath here
},
InAppBrowser: {
screen: InAppBrowserStack,
defaultNavigationOptions: {
tabBarVisible: true
}
},
FCMModal: {
screen: ModalStack
}
},
{
initialRouteName: "main",
headerMode: "none"
}
);
const AppContainer = createAppContainer(rootStack);
export default class App extends Component {
render() {
return (
<AppContainer
ref={navigatorRef => {
NavigationService.setTopLevelNavigator(navigatorRef);
}}
/>
);
}
}
Модальный класс
import React, { Component } from 'react';
import { Modal, Text, TouchableHighlight, View } from 'react-native';
export default class FCMModal extends Component {
state = {
modalVisible: true,
};
setModalVisible(visible) {
this.setState({modalVisible: visible});
}
render() {
return (
<View style={{width: 600, height: 400, borderWidth: 2, borderColor: 'red', opacity: 0.5}}>
<Modal
animationType="slide"
transparent={true}
visible={this.state.modalVisible}
onRequestClose={() => {console.log("CLOSING MODAL!")}}>
<View style={{marginTop: 22}}>
<View>
<Text>Hello World!</Text>
<TouchableHighlight
onPress={() => {
this.setModalVisible(false);
}}>
<Text>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
</View>
);
}
}