Глубокие ссылки в уведомлениях о реактивной реакции - PullRequest
0 голосов
/ 03 сентября 2018

Я использую реагирующую родную базу данных с системой обмена сообщениями для доставки уведомлений в мое приложение с облачными функциями, с admin.messaging (). Send (message), очень похоже на следующее: https://medium.com/the-modern-development-stack/react-native-push-notifications-with-firebase-cloud-functions-74b832d45386.

Я получаю уведомления, когда приложение находится в фоновом режиме. Прямо сейчас я отправляю текст в теле уведомления, например, «новое местоположение было добавлено на карту». Я хочу иметь возможность добавить какую-то глубокую ссылку, чтобы при смахивании View на уведомление (например, на iOS) я попадал на определенный экран внутри приложения. Как передать данные из уведомления в приложение?

Я использую реагирующую нативную навигацию в приложении. Я могу найти код только для глубоких ссылок внутри приложения (https://wix.github.io/react-native-navigation/#/deep-links?id=deep-links).

Ответы [ 3 ]

0 голосов
/ 09 ноября 2018

Я думаю, что у вас все в порядке с "как работает уведомление Firebase" ... причина этого, вот только описание логики, как вы можете Deeplinking в ваше приложение.

Если вы отправляете уведомление, добавьте поле данных. Допустим, в вашем приложении есть Tab-Navigator и разделы «Новости», «Сервис» и «Обзор». В вашем Push-уведомлении - поле данных (назовем его «jumpToScreen», вы определяете свое значение:

jumpToScreen = Сервис

Полагаю, у вас все еще есть обработчик для получения уведомлений от Firebase. Поэтому создайте класс /lib/MessageHandler.js и поместите свою бизнес-логику внутрь.

import firebase from 'react-native-firebase';

/*
 * Get a string from Firebase-Messages and return the Screen to jump to
 */
const getJumpPoint = (pointer) => {
  switch (pointer) {
    case 'News':
      return 'NAV_NewsList'; // <= this are the names of your Screens
    case 'Service':
      return 'NAV_ServiceList';
    case 'Review':
      return 'NAV_ReviewDetail';
    default: return false;
  }
};

const MessageHandler = {
  /**
   *  initPushNotification  initialize Firebase Messaging
   *  @return fcmToken String
   */
  initPushNotification: async () => {
    try {
      const notificationPermission = await firebase.messaging().hasPermission();
      MessageHandler.setNotificationChannels();

      if (notificationPermission) {
        try {
          return await MessageHandler.getNotificationToken();
        } catch (error) {
          console.log(`Error: failed to get Notification-Token \n ${error}`);
        }
      }
    } catch (error) {
      console.log(`Error while checking Notification-Permission\n ${error}`);
    }
    return false;
  },
  clearBadges:  () => {
    firebase.notifications().setBadge(0);
  },
  getNotificationToken: () => firebase.messaging().getToken(),
  setNotificationChannels() {
    try {
      /* Notification-Channels is a must-have for Android >= 8 */
      const channel = new firebase.notifications.Android.Channel(
        'app-infos',
        'App Infos',
        firebase.notifications.Android.Importance.Max,
      ).setDescription('General Information');

      firebase.notifications().android.createChannel(channel);
    } catch (error) {
      console.log('Error while creating Push_Notification-Channel');
    }
  },
  requestPermission: () => {
    try {
      firebase.messaging().requestPermission();
      firebase.analytics().logEvent('pushNotification_permission', { decision: 'denied' });
    } catch (error) {
      // User has rejected permissions
      firebase.analytics().logEvent('pushNotification_permission', { decision: 'allowed' });
    }
  },
  foregroundNotificationListener: (navigation) => {
    // In-App Messages if App in Foreground
    firebase.notifications().onNotification((notification) => {
      MessageHandler.setNotificationChannels();
      navigation.navigate(getJumpPoint(notification.data.screen));
    });
  },
  backgroundNotificationListener: (navigation) => {
    // In-App Messages if App in Background
    firebase.notifications().onNotificationOpened((notificationOpen) => {
      const { notification } = notificationOpen;
      notification.android.setChannelId('app-infos');
      if (notification.data.screen !== undefined) {
        navigation.navigate(getJumpPoint(notification.data.screen));
      }
    });
  },
  appInitNotificationListener: () => {
    // In-App Messages if App in Background
    firebase.notifications().onNotificationOpend((notification) => {
      notification.android.setChannelId('app-infos');
      console.log('App-Init: Da kommt ne Message rein', notification);
      firebase.notifications().displayNotification(notification);
    });
  },
};

export default MessageHandler;

В вашем index.js вы можете подключить его так:

import MessageHandler from './lib/MessageHandler';
export default class App extends Component {
    state = {
      loading: null,
      connection: null,
      settings: null,
    };
async componentDidMount() {
    const { navigation } = this.props;
    await MessageHandler.initPushNotification();
    this.notificationForegroundListener = MessageHandler.foregroundNotificationListener(navigation);
    this.notificationBackgroundListener = MessageHandler.backgroundNotificationListener(navigation);

    this.setState({ loading: false, data });
  }

    componentWillUnmount() {
        this.notificationForegroundListener();
        this.notificationBackgroundListener();
    }
    async componentDidMount() {
      MessageHandler.requestPermission();
      AppState.addEventListener('change', this.handleAppStateChange);
      MessageHandler.clearBadges();
    }

    componentWillUnmount() {
      AppState.removeEventListener('change', this.handleAppStateChange);
    }
    handleAppStateChange = (nextAppState) => {
        if (nextAppState.match(/inactive|background/)) {
           MessageHandler.clearBadges();
        }
    ....

Я надеюсь, что это даст вам идею, как реализовать это для ваших нужд.

0 голосов
/ 10 ноября 2018

Мое решение состояло в том, чтобы добавить, какую информацию мне нужно в объекте данных объекта сообщения уведомления:

в функциях / index.js:

  let message = {
    notification: {
      body: `new notification `
    },
    token: pushToken,
    data: {
      type: 'NEW_TRAINING',
      title: locationTitle
    }
  };

и выполните следующие действия в приложении для навигации:

this.notificationOpenedListener =
      firebase.notifications().onNotificationOpened((notificationOpen: NotificationOpen) => {
      if (notification.data.type === 'NEW_TRAINING') {
        this.props.navigator.push({
          screen: 'newtrainingscreen',
          title: notification.data.title,
          animated: true
        });
      }
0 голосов
/ 05 сентября 2018

Я думаю, вам не нужно использовать ни глубокие ссылки, ни динамические ссылки, а просто правильно использовать Firebase / Уведомления. На вашем месте я бы добавил следующую логику в метод componentDidMount вашего родительского контейнера:

async componentDidMount() {

    // 1. Check notification permission
    const notificationsEnabled = await firebase.messaging().hasPermission();
    if (!notificationsEnabled) {
        try {
            await firebase.messaging().requestPermission(); // Request notification permission
            // At this point the user has authorized the notifications
        } catch (error) {
            // The user has NOT authorized the notifications
        }
    }

    // 2. Get the registration token for firebase notifications
    const fcmToken = await firebase.messaging().getToken();
    // Save the token

    // 3. Listen for notifications. To do that, react-native-firebase offer you some methods:
    firebase.messaging().onMessage(message => { /*  */ })

    firebase.notifications().onNotificationDisplayed(notification => { /* */ })

    firebase.messaging().onNotification(notification => { /*  */ })

    firebase.messaging().onNotificationOpened(notification => { 
        /* For instance, you could use it and do the NAVIGATION at this point
        this.props.navigation.navigate('SomeScreen');
        // Note that you can send whatever you want in the *notification* object, so you can add to the notification the route name of the screen you want to navigate to.
        */
    })

}

Документацию можно найти здесь: https://rnfirebase.io/docs/v4.3.x/notifications/receiving-notifications

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...