类型错误:firebase.default.messaging 不是一个函数(在 '_firebase.default.messaging()' 中,'firebase.default.messaging 是未定义的)

IT技术 reactjs firebase react-native push-notification expo
2021-05-10 00:41:42

我想使用 firebase 云函数发送通知,所以我试图使用 firebase.messaging().getToken() 获取令牌,但我不断收到错误消息:

类型错误:firebase.default.messaging 不是一个函数(在 '_firebase.default.messaging()' 中,'firebase.default.messaging 是未定义的)

我已经以 5 种不同的方式安装了 firebase 和 firebase/messages,但似乎无法克服这个错误,所以我认为这些方法肯定是过时的,或者我做错了什么。

这是我的代码:

import * as firebase from 'firebase'
const Firebase = firebase.initializeApp(firebaseConfig);
export default Firebase

这是我收到错误的地方:

Token : Firebase.messaging().getToken()

我不确定我是否缺少某些依赖项或任何此类内容,因此非常感谢任何帮助。我一直在直接从 firebase 文档安装东西作为 web 到目前为止一直在工作。

我也在使用 expo managed react native

谢谢

还有一些替代方法可以使用更好的事件侦听器在后台发送通知吗?

3个回答

你发帖已经有一段时间了,但我也遇到了同样的错误,所以我会分享一些关于它的发现。您正在寻找的解决方案是项目符号 3。

1) Firebase JavaScript SDK 适用于 Node.js 应用程序尽管 firebase sdk 包可以像 react-native/expo 项目中的任何其他 npm 包一样直接安装和使用,但它意味着在浏览器或 node.js 运行时上运行。

这特别令人困惑,因为一些 firebase Api 方法(例如 firebase.auth 和 firebase.database)在本机应用程序上工作,而其他人则没有。我猜这是因为某些方法仅依赖于执行 HTTP 请求的能力。

实际上,firebase sdk 官方文档页面没有 react-native 部分。如果您查看JavaScript 部分,然后单击将 Firebase 添加到您的 JavaScript 项目,您将看到预期用途包括 Web 应用程序和 node.js 桌面应用程序(不确定在哪些运行时 IoT 应用程序上运行):

在此处输入图片说明

如果您仍想使用 firebase sdk,则应考虑使用React Native Firebase等库,该库旨在解决在 node.js 运行时之外使用 JavaScript sdk 的问题。我自己还没有尝试过,但查看了他们的网站,看起来将其集成到世博会管理的工作流程中并不容易。

2) 导入@firebase/messaging 也不是一个选项:正如在这个答案中所建议的,显式导入消息module不会解决 react-native/expo 项目的问题。同样,如上所述,因为本机应用程序不在 node.js/browser 运行时上运行。事实上,它使事情变得更糟,因为它试图加载不可用的依赖项:

[09:56:33] ReferenceError: Can't find variable: IDBIndex

3) 在 Expo 中获取用户设备通知推送令牌:由于您已经在使用 expo,您可以使用expo-notificationsmodule获取设备推送令牌,这将返回您可以从 Cloud Functions 使用的令牌发送通知通过firebase-admin sdk下面是一些示例代码,用于获取推送令牌并将其存储在实时数据库中(稍后从云函数中使用):

import * as Notifications from 'expo-notifications';
import * as Permissions from 'expo-permissions';
import firebase from 'firebase';

export const getDevicePushToken = () => {
    return Permissions.getAsync(Permissions.NOTIFICATIONS)
        .then((response) =>
            response.status === 'granted'
                ? response
                : Permissions.askAsync(Permissions.NOTIFICATIONS)
        )
        .then((response) => {
            if (response.status !== 'granted') {
                return Promise.reject(new Error('Push notifications permission was rejected'));
            }

            return Notifications.getDevicePushTokenAsync();
        })
        .then(token => {
            firebase.database().ref('...').update({ pushToken: token.data });
        })
        .catch((error) => {
            console.log('Error while registering device push token', error);
        });
};

干杯!

当我尝试使用 jest 编写单元测试和模拟 firebase-admin 时,我收到了类似的消息。

我正在编写我的版本,以防它对某人有所帮助。

我在嘲笑时遇到了错误firebase-adminfirebase-admin像下面这样开玩笑

jest.mock('firebase-admin');

但我开始收到以下错误:

firebase_admin_1.default.messaging is not a function

它即将到来是因为在应用程序代码中,我是这样使用的firebase-admin

await admin.messaging().send(message) 

(消息是TokenMessage 的一个实例

问题是我没有嘲笑成员变量和成员方法。这里是调用的成员方法messaging和嵌套成员方法(请参阅该方法被调用,然后被调用的值)。所需要的只是模拟这些,如下所示:messagingsendmessagingadminsendadmin.messaging()

jest.mock('firebase-admin', () => ({
  credential: {
    cert: jest.fn(),
  },
  initializeApp: jest.fn(),
  messaging: jest.fn().mockImplementation(() => {
    return {
      send: jest
        .fn()
        .mockReturnValue('projects/name_of_project/messages/message_id'),
    };
  }),
}));

(请注意,我还根据最初的要求模拟了其他成员变量/方法。您可能也需要这些模拟)

Firebase 为 React Native 0.6 版更新了自身 + 以下解决方案将起作用。

import { firebase } from '@react-native-firebase/messaging';
await firebase.messaging().registerDeviceForRemoteMessage();
firebase.messaging().getToken();

解决方案2:-

import messaging from '@react-native-firebase/messaging';
await messaging(). registerDeviceForRemoteMessage ();
await messaging().getToken();