Firebase 无法自动进行身份验证以调用云功能

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

云函数(第 2 代)(当我允许未经身份验证的调用时,该函数被正确调用,并且结果也正确。但是,当我将函数配置为需要身份验证时,会出现问题。)

import functions_framework
from google.auth import default
from googleapiclient.discovery import build
from flask import jsonify


@functions_framework.http
def verify_purchase_http(request):
    """HTTP Cloud Function to verify Android subscription purchases."""
    try:
        # Use Application Default Credentials (ADC)
        credentials, project = default(scopes=['https://www.googleapis.com/auth/androidpublisher'])
        androidpublisher = build('androidpublisher', 'v3', credentials=credentials)
    except Exception as e:
        print("Failed to initialize credentials or service: ", str(e))
        return jsonify({"error": "Failed to initialize credentials or service"}), 500

    request_json = request.get_json(silent=True)
    if request_json:
        # Extract the token depending on the structure
        if 'data' in request_json:
            purchase_token = request_json['data'].get('token')
        else:
            purchase_token = request_json.get('token')
    else:
        return jsonify({"error": "Invalid request format"}), 400

    package_name = "" #Already added
    subscription_id = "premium"

    if not purchase_token:
        print("no token found")
        return jsonify({"error": "Token is required"}), 400

    try:
        subscription = androidpublisher.purchases().subscriptions().get(
            packageName=package_name,
            subscriptionId=subscription_id,
            token=purchase_token
        ).execute()

        return jsonify({"data": subscription}), 200
    except Exception as e:
        print("Error calling Google Play API: ", str(e))
        return jsonify({"error": str(e)}), 500

调用函数(Android Kotlin)

private fun testVerifyPurchase() {
        // Hardcoded test purchase token
        val testPurchaseToken = "" #Added test purchase token

        Log.d("PremiumFragment", "Testing verify purchase with token: $testPurchaseToken")

        // Call Firebase function
        verifyPurchaseWithFirebase(testPurchaseToken)
    }

    private fun verifyPurchaseWithFirebase(purchaseToken: String) {

        // Get the currently signed-in user
        val user = FirebaseAuth.getInstance().currentUser

        user?.getIdToken(true)?.addOnCompleteListener { idTokenTask ->
            if (idTokenTask.isSuccessful) {
                val idToken = idTokenTask.result?.token
                Log.d("PremiumFragment", "ID Token: $idToken")

                // Ensure the ID token is not null
                if (idToken != null) {
                    val data = hashMapOf(
                        "token" to purchaseToken
                    )

                    Log.d("PremiumFragment", "Verifying purchase with token: $purchaseToken")
                    Log.d("PremiumFragment", "Data to send to Firebase: $data")

                    functions
                        .getHttpsCallable("verify_purchase")
                        .call(data)
                        .addOnCompleteListener { task ->
                            if (task.isSuccessful) {
                                Log.d(
                                    "PremiumFragment",
                                    "Purchase verified successfully with Firebase"
                                )
                                val result = task.result?.data as? Map<String, Any>
                                if (result != null) {
                                    Log.d("PremiumFragment", "Result from Firebase: $result")
                                    // Update the UI or take necessary actions based on the result
                                } else {
                                    Log.e(
                                        "PremiumFragment",
                                        "No data received from Firebase function"
                                    )
                                }
                            } else {
                                Log.d("PremiumFragment", task.result.toString())
                                Log.e(
                                    "PremiumFragment",
                                    "Failed to verify purchase with Firebase",
                                    task.exception
                                )
                            }
                        }
                }
            }
        }
    }

错误

com.google.android.gms.tasks.RuntimeExecutionException:com.google.firebase.functions.FirebaseFunctionsException:未经身份验证

我不明白,我该怎么办?我已经检查了有关此事的文档,如果我使用 firebase,似乎应该自动处理身份验证。

对于可调用对象,Firebase 身份验证令牌、FCM 令牌和应用程序检查令牌(如果可用)会自动包含在请求中。 触发器自动反序列化请求正文并验证身份验证令牌。

我已将云运行调用者角色添加到默认计算服务帐户(即构建服务帐户)。

有人可以解释一下为什么这没有自动验证吗?此外,如果没有解决这个问题,有人可以建议一个替代方案吗?我对功能部署和Android开发总体来说是新手,所以我可能误解了一些东西,请耐心等待,谢谢!

python firebase google-cloud-functions
1个回答
0
投票
您没有编写

可调用函数 - 您编写了一个普通的HTTP 函数。 我建议查看链接的文档,以更好地理解它们的编写方式之间的差异。 如果您想要可调用函数,则可以使用 @https_fn.on_call

 而不是 
@https_fn.on_request
(以及其他差异)来注释该函数。

© www.soinside.com 2019 - 2024. All rights reserved.