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
相关产品推荐
相关产品推荐

