如何在从 Firebase 收到后台消息后更改 mobx 状态?

问题描述 投票:0回答:1

在我的项目中,我像这样设置了 firebase:

import { initializeApp } from 'firebase/app';
import {
    getMessaging,
    getToken,
    onMessage,
    isSupported
} from 'firebase/messaging';

import store from './flag';
import { setToken } from './flag';

export const VAPID_KEY = process.env.REACT_APP_FIREBASE_VAPID_KEY

export const firebaseConfig = {
    apiKey:  process.env.REACT_APP_FIREBASE_apiKey,
    authDomain: process.env.REACT_APP_FIREBASE_authDomain,
    databaseURL: process.env.REACT_APP_FIREBASE_databaseUrl,
    projectId: process.env.REACT_APP_FIREBASE_projectId,
    storageBucket: process.env.REACT_APP_FIREBASE_storageBucket,
    messagingSenderId: process.env.REACT_APP_FIREBASE_messagingSenderId,
    appId: process.env.REACT_APP_FIREBASE_appId,
    measurementId:  process.env.REACT_APP_FIREBASE_measurementId
};


//Initialize Firebase Messaging
const InitializeMessaging = () => {
    const app = initializeApp(firebaseConfig);
    isSupported().then(is_supported => {
        if (is_supported) {
            requestForToken().then(fcm_token => {
               store.dispatch(setToken(fcm_token));
            });
        }
    });
};

const requestForToken = () => {
    const messaging = getMessaging();
    return getToken(messaging, {
        vapidKey: VAPID_KEY
    })
    .then(currentToken => {
            if (currentToken) {
                return currentToken;
            } else {
                console.log(
                    'No registration token available. Request permission to generate one.'
                );
            }
        })
        .catch(err => {
            console.error('An error occurred while retrieving token. ', err);
        });
};

InitializeMessaging();

export const onMessageListener = () =>
    
    new Promise(resolve => {
        onMessage(getMessaging(), payload => {
            resolve(payload);
        });
});

我有一个商店,在收到消息后我会更改 mobx 状态(

flag.js
):

import { configureStore } from '@reduxjs/toolkit'
import { onMessageListener } from './firebase';


const initialState = { flag: true, token: "" }

function flagReducer(state = initialState, action) {
  // Check to see if the reducer cares about this action
  if (action.type === 'flag/change') {
    // If so, make a copy of `state`
    return {
      ...state,
      // and update the copy with the new value
      flag:action.payload
    }
  }

  if (action.type === 'flag/token') {
    return {
      ...state,
      // and update the copy with the new value
      token:action.payload
    }
  }
  // otherwise return the existing state unchanged
  return state
}

const store = configureStore({ reducer: flagReducer });

export const setFlag = active => ({
    type: 'flag/change',
    payload: active==='true'
});

export const setToken = token => ({
  type: 'flag/token',
  payload: token
});

onMessageListener().then(payload => {
   
})
.catch(err => console.log('failed: ', err));

navigator.serviceWorker.addEventListener(
  'message',
  function(event) {
    const message = event.data.data;
    if(typeof message !== 'undefined' && typeof message['flag'] !== 'undefined' ) {
        store.dispatch(setFlag(message.flag));
    }
  }
);

export default store;

我的状态有一个从 firebase 消息切换的标志。

我还有以下工人(

firebase-messaging-sw.js
):

importScripts('https://www.gstatic.com/firebasejs/8.2.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.2.0/firebase-messaging.js');


// Initialize the Firebase app in the service worker by passing the generated config
const firebaseConfig = {
  apiKey: `REPLACE_WITH_YOUR_FIREBASE_MESSAGING_API_KEY`,
  authDomain: `REPLACE_WITH_YOUR_FIREBASE_MESSAGING_AUTH_DOMAIN`,
  projectId: `REPLACE_WITH_YOUR_FIREBASE_MESSAGING_PROJECT_ID`,
  storageBucket: `REPLACE_WITH_YOUR_FIREBASE_MESSAGING_STORAGE_BUCKET`,
  messagingSenderId: `REPLACE_WITH_YOUR_FIREBASE_MESSAGING_SENDER_ID`,
  appId: `REPLACE_WITH_YOUR_FIREBASE_MESSAGING_APP_ID`,
  measurementId: `REPLACE_WITH_YOUR_FIREBASE_MESSAGING_MEASUREMENT_ID`,
};


firebase.initializeApp(firebaseConfig);

// Retrieve firebase messaging
const messaging = firebase.messaging();

// Handle incoming messages while the app is not in focus (i.e in the background, hidden behind other tabs, or completely closed).
messaging.onBackgroundMessage(function(payload) {
  console.log('Received background message', payload);

  // How I can send the received message upon mobx
 
});

我想要实现的是,当我收到后台消息时,我也希望修改我所在州的标志。有办法吗?

我想要的是将消息从

firebase-messaging-sw.js
传播到
flag.js
,这样我也可以更新 redux 状态。

我的应用程序使用状态来显示基于状态标志的徽标:

import { connect } from 'react-redux';
import logo from './logo.svg';

function Logo({shown,token}){
    return (
      <img src={logo} className="App-logo" style={{display:!shown?"none":""}} alt="logo" />
    );
}

const mapStateToProps = state => {
    console.log(state);
    return {
      shown: state.flag,
    };
};

export default connect(
    mapStateToProps,
)(Logo);
javascript reactjs firebase firebase-cloud-messaging mobx
1个回答
0
投票

这可以通过在

firebase-messaging-sw.js
放置以下内容来实现:

messaging.onBackgroundMessage(function(payload) {
  console.log('Received background message', payload);

  // Propagate message upon UI
  if(typeof payload.data !== 'undefined' && typeof payload.data['flag'] !== 'undefined' ) {
    self.clients.matchAll({includeUncontrolled: true}).then(function (clients) {
      //you can see your main window client in this list.
      clients.forEach(function(client) {
          client.postMessage({...payload});
      });
    })
  }
});

并在

flag.js
文件中放置:

navigator.serviceWorker.addEventListener(
  'message',
  function(event) {
    const message = event.data.data;
    if(typeof message !== 'undefined' && typeof message['flag'] !== 'undefined' ) {
        store.dispatch(setFlag(message.flag));
    }
  }
);


代码解释

上面的代码所做的是:

self.clients.matchAll({includeUncontrolled: true}).then(function (clients) {
      //you can see your main window client in this list.
      clients.forEach(function(client) {
          client.postMessage({...payload,'type':'firebaseBG'});
      });
    })

我们通过一个特殊事件将消息传播回前端,该事件通过以下方式处理:

navigator.serviceWorker.addEventListener(
  'message',
  function(event) {
     // Event handled here
  }
);

消息有效负载可通过以下方式在活动中获得:

    event.data.data;
© www.soinside.com 2019 - 2024. All rights reserved.