【问题标题】:How do I properly call an HTTPs callable function from my app?如何从我的应用程序中正确调用 HTTPs 可调用函数?
【发布时间】:2021-05-05 22:06:07
【问题描述】:

我按照一些指南编写了一个云函数。现在我需要从我的应用程序中调用它。我做了以下事情:

Kotlin 代码:

class ActivitySignup : AppCompatActivity() {

    private lateinit var functions: FirebaseFunctions
    private lateinit var user: String

    override fun onCreate(savedInstanceState: Bundle?) {
    ...
    functions = Firebase.functions
    ...
    submitbutton.setOnClickListener() {
            Log.e(tag,"Clicked submit")
            userEditTxt = findViewById(R.id.et_user)
            user = userEditTxt.text.toString().trim()

         auth.createUserWithEmailAndPassword(email, password)
            .addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.i(tag, "User created")

                    functions.getHttpsCallable("addUser")
                    .call(user)
                    .continueWith { task ->
                        // This continuation runs on either success or failure, but if the task
                        // has failed then result will throw an Exception which will be
                        // propagated down.
                        val result = task.result?.data as String
                        Log.e("result", result)
                        result
                    }

                    val intent = Intent(this, ActivityGroups::class.java)
                    startActivity(intent)
                    finish()

                } else {
                    // If sign in fails, display a message to the user.
                    Log.w(tag, "failure", task.exception)
                    Toast.makeText(baseContext, "Authentication failed.",
                        Toast.LENGTH_SHORT).show()
                }

        }

    }

index.ts 中的云函数:

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();

exports.addUser = functions.https.onCall((data, context) => {
  console.log('addUser: ', data.username);

  const username = data.username
  functions.auth.user().onCreate(user => {
    const doc = admin.firestore().collection('users').doc();
    return doc.set({
      createDate: admin.firestore.FieldValue.serverTimestamp(),
      modifiedDate: admin.firestore.FieldValue.serverTimestamp(), 
      username: username,
      email: user.email,    
      stat: 1, //0 = banned, 1 = normal
      uid: user.uid,
      rowpointer: doc.id,
    });
  });

但是,有两个问题:

  1. Android Studio 以红色突出显示 Firebase.functions 的“功能”部分。错误是Unresolved reference: functions

  2. 当我在 Visual Studio 中执行firebase serve 时,我得到了以下信息:

  • functions[addUser]:http 函数已初始化 (http://localhost:5000/APPNAME-cf4da/us-central1/addUser)。

i 函数:开始执行“addUser”

{"severity":"WARNING","message":"请求的方法无效。GET"}

{"severity":"ERROR","message":"无效请求,无法处理。"}

i 个函数:在 ~1s 内完成“addUser”

我对 Android 开发/云功能还很陌生,所以我觉得我只是在某个地方犯了一个菜鸟错误......

【问题讨论】:

  • 我在您分享的 Android 代码中没有看到对 Callable 函数的任何调用。调用看起来像这里文档中的示例:firebase.google.com/docs/functions/callable#call_the_function您确定这就是重现错误所需的全部内容吗?
  • @FrankvanPuffelen 对此感到抱歉!我添加了可调用对象在 Kotlin 代码中的位置。过去有人告诉我,我在问题中放入了太多代码......所以我试图只在我的问题中放入重要的东西。 Kotlin 应用程序还有什么标准?
  • @FrankvanPuffelen 您链接的文档正是我遵循的让我达到这一点的文档。正是这部分给了我问题:firebase.google.com/docs/functions/…
  • 感谢调用函数的 Android 代码。 .call(user) 是什么?
  • 已修复!对此感到抱歉。

标签: typescript firebase kotlin google-cloud-functions


【解决方案1】:

这种嵌套没有意义:

exports.addUser = functions.https.onCall((data, context) => {
  console.log('addUser: ', data.username);

  const username = data.username
  functions.auth.user().onCreate(user => {
    const doc = admin.firestore().collection('users').doc();
    return doc.set({
      createDate: admin.firestore.FieldValue.serverTimestamp(),
      modifiedDate: admin.firestore.FieldValue.serverTimestamp(), 
      username: username,
      email: user.email,    
      stat: 1, //0 = banned, 1 = normal
      uid: user.uid,
      rowpointer: doc.id,
    });
  });

您似乎试图在 functions.https.onCall 函数中注册 functions.auth.user().onCreate 函数,这是不可能的。所有 Cloud Functions 都需要是您的 index.js 文件的顶级导出。

我的最佳猜测是,您希望将有关刚刚创建的用户的信息从您的 Android 代码传递到 Cloud Function,在这种情况下,应该在传递给 onCall(data, context)datsa 参数中。如果您实际上“只是”想了解当前用户,您也可以从 context.auth 获取,如 writing and deploying a callable Cloud Function 上的文档中所示。

这可能更接近,尽管您的原始代码中可能存在更多问题:

exports.addUser = functions.https.onCall((data, context) => {
  console.log('addUser: ', data.username);
  const username = data.username;
  const email = data.email;
  const uid = context.auth.uid; // ? get uid from context
  const doc = admin.firestore().collection('users').doc(uid); // ? use uid as document ID
  return doc.set({
      createDate: admin.firestore.FieldValue.serverTimestamp(),
      modifiedDate: admin.firestore.FieldValue.serverTimestamp(), 
      username: username,
      email: email,    
      stat: 1, //0 = banned, 1 = normal
      uid: uid
  });
});

【讨论】:

  • 这给出了指向context.auth.uid 的错误。错误是Object is possibly 'undefined'
  • 确实可以,因为我主要专注于尝试向您展示该做什么的大纲。将此视为伪代码,向您展示为什么您的代码不起作用的一些关键点。我建议您搜索有关错误消息的更多信息,这不是 Firebase 特定的。
猜你喜欢
  • 1970-01-01
  • 2023-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多