You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity/Vuforia上传目标图像与叠加视频遇权限及实现错误求助

问题:Vuforia上传认证失败与Firebase数据保存报错

相关代码

保存逻辑代码

async void OnSaveButtonClicked()
{
    string title = titleInputField.text;
    if (string.IsNullOrEmpty(title))
    {
        Debug.LogError("Title cannot be empty.");
        return;
    }

    if (videoRenderTexture == null)
    {
        Debug.LogError("RenderTexture is null.");
        return;
    }

    Texture2D overlayTexture = GetTextureFromUIImage(overlayImageDisplay);

    try
    {
        await UploadImageToFirebase(overlayTexture);

        if (string.IsNullOrEmpty(capturedImageUrl))
        {
            Debug.LogError("Captured image URL is not set.");
            return;
        }

    
        await UploadImageToVuforia(overlayTexture);

        if (!string.IsNullOrEmpty(selectedVideoPath))
        {
            await UploadVideoToFirebase(selectedVideoPath);
        }

        string key = databaseReference.Push().Key;
        currentARExperienceData = new Dictionary<string, object>
        {
            { "title", title },
            { "capturedImageUrl", capturedImageUrl },
            { "overlayUrl", overlayUrl }
        };


        Debug.Log("Attempting to save data to Firebase...");
        await databaseReference.Child(key).UpdateChildrenAsync(currentARExperienceData);
        Debug.Log("Data saved successfully.");


        Debug.Log("AR experience saved successfully.");
        panelSwitcher.OpenPanel("ProfilePanel");
    }
    catch (Exception e)
    {
        Debug.LogError("Failed to save AR experience: " + e.Message);
    }
}

Vuforia上传与签名代码

private async Task UploadImageToVuforia(Texture2D image)
{
byte[] imageBytes = EncodeTextureToJPG(image);

    string targetName = "MyTarget";
    string accessKey = "";
    string secretKey = "";
    string endpoint = "https://vws.vuforia.com";

    var request = new HttpRequestMessage(HttpMethod.Post, $"{endpoint}/targets")
    {
        Content = new MultipartFormDataContent
        {
            { new ByteArrayContent(imageBytes), "file", "image.jpg" },
            { new StringContent(targetName), "name" }
        }
    };

    string date = DateTime.UtcNow.ToString("r");
    string stringToSign = $"{request.Method}\n\n\n{imageBytes.Length}\n{date}\n/targets";
    string signature = GenerateSignature(stringToSign, secretKey);

    request.Headers.Add("Authorization", $"VWS {accessKey}:{signature}");
    request.Headers.Add("Date", date);

    HttpClient client = new HttpClient();
    try
    {
        HttpResponseMessage response = await client.SendAsync(request);
        string responseBody = await response.Content.ReadAsStringAsync(); 

        if (response.IsSuccessStatusCode)
        {
            Debug.Log("Image successfully uploaded to Vuforia!");
        }
        else
        {
            Debug.LogError($"Vuforia upload failed: {response.ReasonPhrase}");
            Debug.LogError("Response body: " + responseBody); 
        }
    }

    catch (Exception e)
    {
        Debug.LogError("Vuforia upload failed: " + e.Message);
    }
}

private string GenerateSignature(string stringToSign, string secretKey)
{
    var encoding = new System.Text.ASCIIEncoding();
    byte[] keyBytes = encoding.GetBytes(secretKey);
    byte[] messageBytes = encoding.GetBytes(stringToSign);
    using (var hmacsha1 = new System.Security.Cryptography.HMACSHA1(keyBytes))
    {
        byte[] hashmessage = hmacsha1.ComputeHash(messageBytes);
        return Convert.ToBase64String(hashmessage);
    }
}

错误信息

upload failed: Unauthorized
UnityEngine.Debug:LogError (object)
CreateARManager/d__37:MoveNext () (at Assets/Scripts/CreateARManager.cs:366)
UnityEngine.UnitySynchronizationContext:ExecuteTasks ()
Response body: {"result_code":"AuthenticationFailure","transaction_id":"e58338366f80453fa91d67fbc0f6baf8"}
UnityEngine.Debug:LogError (object)
CreateARManager/d__37:MoveNext () (at Assets/Scripts/CreateARManager.cs:367)
UnityEngine.UnitySynchronizationContext:ExecuteTasks ()
Failed to save AR experience: The method or operation is not implemented.
UnityEngine.Debug:LogError (object)
CreateARManager/d__33:MoveNext () (at Assets/Scripts/CreateARManager.cs:257)
System.Threading.Tasks.TaskCompletionSource`1:SetResult (int)
Firebase.FutureVoid/<>c__DisplayClass4_0:b__0 () (at /home/runner/work/firebase-unity-sdk/firebase-unity-sdk/linux_unity/app/swig/Firebase.App_fixed.cs:1368)
Firebase.FutureVoid:SWIG_CompletionDispatcher (int) (at /home/runner/work/firebase-unity-sdk/firebase-unity-sdk/linux_unity/app/swig/Firebase.App_fixed.cs:1456)
Firebase.AppUtil:PollCallbacks () (at /home/runner/work/firebase-unity-sdk/firebase-unity-sdk/linux_unity/app/swig/Firebase.App_fixed.cs:4656)
Firebase.Platform.FirebaseAppUtils:PollCallbacks () (at /home/runner/work/firebase-unity-sdk/firebase-unity-sdk/app/platform/FirebaseAppUtils.cs:33)
Firebase.Platform.FirebaseHandler:Update () (at /home/runner/work/firebase-unity-sdk/firebase-unity-sdk/app/platform/Unity/FirebaseHandler.cs:208)
Firebase.Platform.FirebaseMonoBehaviour:Update () (at /home/runner/work/firebase-unity-sdk/firebase-unity-sdk/app/platform/Unity/FirebaseMonoBehaviour.cs:45)

解决方案

解决Vuforia认证失败问题

  • 替换签名算法为SHA256:Vuforia当前要求使用HMAC-SHA256生成签名,原代码使用的HMACSHA1是核心问题。修改签名方法:
    private string GenerateSignature(string stringToSign, string secretKey)
    {
        var encoding = new System.Text.ASCIIEncoding();
        byte[] keyBytes = encoding.GetBytes(secretKey);
        byte[] messageBytes = encoding.GetBytes(stringToSign);
        // 替换HMACSHA1为HMACSHA256
        using (var hmacsha256 = new System.Security.Cryptography.HMACSHA256(keyBytes))
        {
            byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
            return Convert.ToBase64String(hashmessage);
        }
    }
    
  • 校验签名字符串格式:确保stringToSign的换行、参数顺序完全符合Vuforia规范,日期必须为UTC时区的RFC 1123格式,无多余空格或字符
  • 确认密钥正确性:使用Vuforia开发者控制台中的Server Access Keys,复制时避免包含前后空格、换行符,不要混用Client Keys

解决Firebase数据保存报错问题

  • 替换UpdateChildrenAsync为SetValueAsync:新增数据时使用SetValueAsync更适配,避免Update方法的潜在兼容问题:
    await databaseReference.Child(key).SetValueAsync(currentARExperienceData);
    
  • 更新Firebase SDK版本:使用最新稳定版的Firebase Unity SDK,旧版本可能存在API未实现的问题
  • 检查Database权限与引用:确认Realtime Database已启用,databaseReference指向正确节点,测试阶段可临时设置宽松权限规则:
    {
      "rules": {
        ".read": true,
        ".write": true
      }
    }
    

内容的提问来源于stack exchange,提问作者Ryan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:48:15