无法使用 android 模拟器上的 Firestore 模拟器访问云 Firestore 后端

Posted

技术标签:

【中文标题】无法使用 android 模拟器上的 Firestore 模拟器访问云 Firestore 后端【英文标题】:could not reach cloud firestore backend with firestore emulator on android emulator 【发布时间】:2020-10-21 04:26:13 【问题描述】:

我的问题是我无法在 android 模拟器上使用 firebase firestore 模拟器从客户端调用 firestore。我已经测试了多个 Android 模拟器。

我收到的错误表明该应用根本无法连接到 Firestore,声称没有互联网连接。以下是完整消息:“@firebase/firestore:, Firestore (7.8.1): 无法到达 Cloud Firestore 后端。连接失败 1 次。最近的错误:FirebaseError: [code=unavailable]: 操作无法完成 这通常表明您的设备目前没有健康的互联网连接。客户端将在离线模式下运行,直到能够成功连接到后端。”

这让我很困惑,因为我的应用可以在 ios 上使用 firebase firestore 模拟器。它也仍然适用于 android 的 firebase 云函数模拟器(没关系。它从未使用云函数)。如果重要的话,在生产环境中使用 firestore 时,该应用也可以在 iOS 和 Android 上正常运行。

我正在使用 Expo 托管工作流创建一个 React Native 应用程序,因此我使用的是 firebase 的 Web SDK。这意味着我必须弹出才能切换到 react-native-firebase。

我还查看了文档,我似乎按照那里的说明进行操作:https://firebase.google.com/docs/emulator-suite/connect_firestore#web

我也遇到了这个问题,我不清楚它们是否相关。 https://github.com/firebase/firebase-js-sdk/issues/2923 如果是这样,我也不确定如何在保留 expo 托管工作流程的同时修复它。

这是我的 Firebase 配置

firebaseConfig.js

import * as firebase from 'firebase';
// Optionally import the services that you want to use
//import "firebase/auth";
//import "firebase/database";
import "firebase/firestore"; // uncommented so I could test locally w/ emulator
import "firebase/functions";
//import "firebase/storage";

// ios id 
  // appId: "1:586841249272:ios:d8b508f7811d7c84e0b20d",

// Initialize Firebase
const firebaseConfig = 
  apiKey: "myApikey",
  authDomain: "fsp2-a670d.firebaseapp.com",
  databaseURL: "https://fsp2-a670d.firebaseio.com",
  projectId: "fsp2-a670d",
  storageBucket: "fsp2-a670d.appspot.com",
  messagingSenderId: "586841249272",
  appId: "1:586841249272:android:fa68525699ea5cdde0b20d"
;

// added .firestore to test firestore locally w/ emulator 
const db = firebase.initializeApp(firebaseConfig).firestore(); 

// for debugging
firebase.firestore.setLogLevel('debug')

// Uncomment the below line to use cloud functions with the emulator
firebase.functions().useFunctionsEmulator('http://localhost:5001')
// firebase.firestore().settings( experimentalForceLongPolling: true );

// uncomment this to test firestore locally w/ emulator 
  db.settings(
    host: "localhost:8080",
    ssl: false
  );

这是文件中从客户端调用 firestore 失败的代码。会的

const More = (navigation) => 
  const [userInfo, setUserInfo] = useState(profilePicture: 'placeholder', userName: '');

  useEffect(() => 
    const changeUserInfo = async () => 
      const userData = await new Promise(function (resolve, reject) 
        // 2 - Copy-paste your code inside this function
        firebase.auth().onAuthStateChanged(user => 
          resolve(user) // this promise is rejected and I need to write the code to handle rejections
        )
      )
      const db = firebase.firestore();
      const uid = userData?.uid;
      if (uid) 
        const userRef = await db.collection('users').doc(uid);
        const user = await userRef.get();
        const userFields = user.data();
        console.log('userFields is: ', userFields);
        const profilePicture, userName = userFields;
        console.log('profilePicture is: ', profilePicture);
        console.log('userName is: ', userName);
        setUserInfo(() => 
          return 
            profilePicture,
            userName,
          
        );
      
    
    changeUserInfo()
  , [userInfo.profilePicture, userInfo.userName]

非常感谢任何帮助!

【问题讨论】:

嘿!您不应该在此处发布您的 API 凭据! @JuanCarlosDurini 你确定吗?根据阅读此内容,我认为没关系:***.com/questions/37482366/… 【参考方案1】:

在 db.settings 中,我需要将主机设置为“10.0.2.2:8080”

为了让云功能正常工作,我需要将 firebase.functions().useFunctionsEmulator('http://localhost:5001') 替换为 firebase.functions().useFunctionsEmulator('http://10.0.2.2:5001 ')

10.0.2.2 是从 Android 模拟器连接到主机的“localhost”的特殊 IP 地址。 https://firebase.google.com/docs/emulator-suite/connect_and_prototype#android_1

【讨论】:

谢谢!事后看来,现在看来很明显 localhost 如何无法在模拟器/设备上工作。就我而言,当使用真手机时,我需要使用我的计算机的 IP 而不是 10.0.2.2。 你知道如何让实时数据库工作吗? @petermir realtimeDatabase.useEmulator('10.0.2.2', 9000)【参考方案2】:

我设法通过使用 Expo 的调试器主机的内置变量来解决这个问题,该变量也适用于物理 iOS 设备:Constants.manifest.debuggerHost?.split(":").shift()

在这里写了一个简短的解释:

https://dev.to/haydenbleasel/using-the-firebase-local-emulator-with-expo-s-managed-workflow-5g5k

【讨论】:

【参考方案3】:

虽然我自己的案例与任何 JS 库/框架无关,而是在使用原生 javascript 时,但我在本地机器上使用 firebase 模拟器时遇到了同样的问题。

在网站上没有任何希望的谷歌搜索后,我发现通过设置 firestore url 并在初始化 firebase 后禁用 SSL 解决了我自己的问题。示例如下:

             /** After: const firestore = firebase.initializeApp("<firebase-config>").firestore() **/

                firestore.settings(
                    host: "localhost:8080",
                    ssl: false
                );

【讨论】:

以上是关于无法使用 android 模拟器上的 Firestore 模拟器访问云 Firestore 后端的主要内容,如果未能解决你的问题,请参考以下文章

“无法连接到远程 VM”将 jdb 连接到 Windows 上的 android 模拟器

应用程序无法部署到 API 19(平台 4.4.2)上的 Android 英特尔模拟器

Android手机上的错误“无法启动地理定位服务代码:2”

Bitrise 上的 Detox 无法在 Android 上运行 - React Native

是否可以在 MAC 上的 Android Studio 中使用 IOS 模拟器设备?

模拟器上的 GPS 没有得到地理修复 - Android