iosfirebasegoogle-cloud-functionsfirebase-app-check

Firebase App Check Throws 401 Error on iOS Devices


I am encountering a 401 error with Firebase App Check on iOS devices and need help identifying the issue.
We are using Firebase App Check to secure our backend API. The setup on Android was successful, and everything works as expected. However, we are facing difficulties with the iOS setup. When using debug tokens on iOS, App Check works fine, but switching to production results in a 401 error.

What We Have Tried:

Possible Issues:

Could someone guide us on what we might be doing wrong? Are there specific settings or configurations on the Apple Developer side or in Xcode that we need to verify?
Or could the issue be with our code setup for integrating Firebase App Check on iOS? Any advice or pointers would be greatly appreciated!

Unity 2022.3.34f1
Firebase 12.0.0
Xcode 15.4
Firebase Cloud Function

verifications: {
  app: "MISSING"
  auth: "VALID"
}
// Logs
2:Firebase.Functions.FunctionsException: Unauthenticated
  at Firebase.Functions.HttpsCallableReference.<CallAsync>b__9_0 (System.Threading.Tasks.Task`1[TResult] task) [0x00000] in <00000000000000000000000000000000>:0
  at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2[TAntecedentResult,TResult].InnerInvoke () [0x00000] in <00000000000000000000000000000000>:0
  at System.Threading.Tasks.Task.Execute () [0x00000] in <00000000000000000000000000000000>:0
  at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <00000000000000000000000000000000>:0
  at System.Threading.Tasks.Task.ExecuteWithThreadLocal (System.Threading.Tasks.Task& currentTaskSlot) [0x00000] in <00000000000000000000000000000000>:0
  at System.Threading.Tasks.Task.ExecuteEntry (System.Boolean bPreventDoubleExecution) [0x00000] in <00000000000000000000000000000000>:0
  at System.Threading.ThreadPoolWorkQueue.Dispatch () [0x00000] in <00000000000000000000000000000000>:0
--- End of stack trace from previous location where exception was thrown ---

  at TestScript.CheckHash () [0x00000] in <00000000000000000000000000000000>:0
  at UnityEngine.UnitySynchronizationContext+WorkRequest.Invoke () [0x00000] in <00000000000000000000000000000000>:0
  at UnityEngine.UnitySynchronizationContext.Exec () [0x00000] in <00000000000000000000000000000000>:0

<CheckHash>d__4:MoveNext()
UnityEngine.UnitySynchronizationContext:Exec()
using System;
using System.Collections;
using System.Collections.Generic;
using _Car_Parking.Scripts.Database;
using Cysharp.Threading.Tasks;
using Firebase.AppCheck;
using Firebase.Functions;
using UnityEngine;

public class TestScript : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        FirebaseInitializer firebaseInitializer = new FirebaseInitializer();
        firebaseInitializer.Initialize();
    }

    public void Check()
    {
        CheckHash().Forget();
    }

    public void GenerateApp()
    {
        GenerateAppAttest().Forget();
    }
    private async UniTaskVoid GenerateAppAttest()
    {
        FirebaseAppCheck.SetAppCheckProviderFactory(AppAttestProviderFactory.Instance);
        Debug.Log("Generrate AppattestToken");
    }
    private async UniTaskVoid CheckHash()
    {
        try
        {
            Debug.Log("result1 start");
            var r  = FirebaseFunctions.DefaultInstance.GetHttpsCallable("PrintHash");
            await r.CallAsync("");
            Debug.Log("result1:" + r);
        }
        catch (Exception e)
        {
            Debug.LogError("1:" + e);
        }

        try
        {
            Debug.Log("result2 start");
            var r  = FirebaseFunctions.DefaultInstance.GetHttpsCallable("PrintHash2");
            await r.CallAsync("");
            Debug.Log("result2:" + r);
        }
        catch (Exception e)
        {
            Debug.LogError("2:" + e);
        }
    }
    
}

Solution

  • It turned out that our Apple Team ID was different, which was causing the issue.