iOS:Twilio 验证 React Native:调用 API 时出现异常

iOS: Twilio Verify for React Native: Exception while calling the API

我正在使用 Twilio Verify for React Native and I'm getting an error (log below) when using their snippet to create a Factor:

export async function createTwilioVerifyFactor(identity) {
  const pushToken = await messaging().getToken()

  const accessTokenResponse = await getTwilioVerifyAccessToken(identity)
  const hashedIdentity = accessTokenResponse.identity
  const accessToken = accessTokenResponse.token

  try {
    const factor = await TwilioVerify.createFactor(
      new PushFactorPayload(
        // factor name
        Device.deviceName ?? 'Unknown Device',
        Constants.manifest.extra.twilioVerifyServiceSid,
        hashedIdentity,
        pushToken,
        accessToken
      )
    )
    if (!factor.sid) throw new Error('Failed to create factor')
    return factor
  } catch (e) { console.log(JSON.stringify(e, null, 2) }
}

我已确保 none 个所需值是 null/undefined,但我仍然遇到错误。

Android 设备没有问题,但 iOS 设备有问题。 try / catch 块导致以下日志:

{
  "nativeStackAndroid": [
    {
      "lineNumber": 95,
      "file": "FactorAPIClient.kt",
      "methodName": "invoke",
      "class": "com.twilio.verify.api.FactorAPIClient$create"
    },
    {
      "lineNumber": 61,
      "file": "FactorAPIClient.kt",
      "methodName": "invoke",
      "class": "com.twilio.verify.api.FactorAPIClient$create"
    },
    {
      "lineNumber": 68,
      "file": "NetworkAdapter.kt",
      "methodName": "execute",
      "class": "com.twilio.verify.networking.NetworkAdapter"
    },
    {
      "lineNumber": 89,
      "file": "FactorAPIClient.kt",
      "methodName": "create",
      "class": "com.twilio.verify.api.FactorAPIClient"
    },
    {
      "lineNumber": 49,
      "file": "FactorRepository.kt",
      "methodName": "create",
      "class": "com.twilio.verify.domain.factor.FactorRepository"
    },
    {
      "lineNumber": 87,
      "file": "PushFactory.kt",
      "methodName": "create",
      "class": "com.twilio.verify.domain.factor.PushFactory"
    },
    {
      "lineNumber": 55,
      "file": "FactorFacade.kt",
      "methodName": "invoke",
      "class": "com.twilio.verify.domain.factor.FactorFacade$createFactor"
    },
    {
      "lineNumber": 43,
      "file": "FactorFacade.kt",
      "methodName": "invoke",
      "class": "com.twilio.verify.domain.factor.FactorFacade$createFactor"
    },
    {
      "lineNumber": 68,
      "file": "Executor.kt",
      "methodName": "run",
      "class": "com.twilio.verify.threading.Task"
    },
    {
      "lineNumber": 1167,
      "file": "ThreadPoolExecutor.java",
      "methodName": "runWorker",
      "class": "java.util.concurrent.ThreadPoolExecutor"
    },
    {
      "lineNumber": 641,
      "file": "ThreadPoolExecutor.java",
      "methodName": "run",
      "class": "java.util.concurrent.ThreadPoolExecutor$Worker"
    },
    {
      "lineNumber": 929,
      "file": "Thread.java",
      "methodName": "run",
      "class": "java.lang.Thread"
    }
  ],
  "userInfo": null,
  "message": "{60401} Exception while calling the API",
  "code": "EUNSPECIFIED",
  "line": 5737,
  "column": 45,
  "sourceURL": "http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=my.app&modulesOnly=false&runModule=true"
}

我可能做错了什么吗?

这里是 Twilio 开发人员布道者。

我在这里看到了几个潜在的问题。首先,错误说:

{60401} Exception while calling the API

Error 60401 表示存在网络错误。您说这不是模拟器中的问题,而是发生在真实设备上。你检查过那些真实设备的网络连接了吗?

其次,您使用 consttry/catch 块中声明 factor 变量,但是您随后尝试在 catch块。在那个阶段,factor 现在超出范围,因为 const 是块范围的。您可能会收到类似“无法读取未定义的属性”的错误。最好在 try 块内完成其余逻辑。

  try {
    const factor = await TwilioVerify.createFactor(
      new PushFactorPayload(
        // factor name
        Device.deviceName ?? 'Unknown Device',
        Constants.manifest.extra.twilioVerifyServiceSid,
        hashedIdentity,
        pushToken,
        accessToken
      )
    )
    if (!factor.sid) throw new Error('Failed to create factor')

    return factor
  } catch (e) { console.log(JSON.stringify(e, null, 2) }
}

我终于找到了为什么此代码无法在 iOS 上运行的答案。 我的错误是我试图在本应使用 APNs 令牌的地方使用 FCM 令牌。 至于 Android,同样的实现突然起作用了,所以我正在更新我的问题标题。

我的解决方案

我创建了一个辅助函数来获取 PNs 令牌,具体取决于使用 FCM 令牌作为后备的平台。

import { Platform } from 'react-native'
import messaging from '@react-native-firebase/messaging'

export default async function getPushNotificationsToken() {
  if (Platform.OS === 'ios') {
    const token = await messaging().getAPNSToken()
    if (token) return token
  }

  return messaging().getToken()
}

我在初始代码中替换了这一行:

const pushToken = await messaging().getToken()
const pushToken = await getPushNotificationsToken()