Что я хочу сделать
Использование класса WebRequest Unity для доступа к API, созданному в функциях Firebase. Нажмите на API, который генерирует подписанный URL-адрес для загрузки с помощью запроса Post, чтобы получить URL-адрес. Загрузка файла с запросом на размещение с использованием извлеченного URL-адреса (максимальный размер файла составляет около 300 МБ). Кроме того, класс WebRequest не поддерживает async / await, поэтому это подтверждается ссылкой на этот сайт .
Проблема
Когда я отправляю запрос Put, мне говорят, что подписанный URL-адрес запрещен для 403 сторона назначения, и подпись не совпадает, поэтому я не могу загрузить файл (я пытался с файлами 5 МБ и 300 МБ, оба не удалось).
Ошибка
<?xml version='1.0' encoding='UTF-8'?><Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided.
Check your Google secret key and signing method.</Message>
<StringToSign>PUT
Что я сделал после проблемы
Я отобразил URL, полученный в Debug.Log, и пропустил запрос Put с командой Curl внизу. URL был сгенерирован и загружен без особого времени, поэтому я подождал около 2-5 секунд, прежде чем запустить его, но он не был загружен и произошла та же ошибка, и я попытался отправить его с руководством официального лица Unity , но не удалось с той же ошибкой.
Что я ищу
Успешные загрузки на подписанные URL-адреса загрузки, созданные в Firebase с использованием класса Unity WebRequest.
Коды
=== генерировать Загрузить подписанный URL (функция Firebase / JavaScript) ===
exports.getSignedUrl = async (req, res) => {
if (req.method !== 'POST') {
// Return a "method not allowed" error
return res.status(405).end();
}
const user = req.body.user;
const roomName = req.body.name;
const snapshot = admin.database();
// Get a reference to the destination file in GCS
const file = storage.bucket("[Firebase Storage Path]").file(req.body.filename);
// Create a temporary upload URL
const times = Date.now();
console.log(times);
const expiresAtMs = times + 5*60*1000; // Link expires in 5 minutes
console.log("expire : " + expiresAtMs);
const config = {
action: 'write',
expires: expiresAtMs
};
file.getSignedUrl(config, async (err, url) => {
if (err) {
console.error(err);
res.status(500).end();
return;
}
res.send(url);
});
};
=== Скрипт загрузки (Unity 2019.3.11 / C# .Net4.x) ===
// data contain file bytes array which I want to upload
// targetURL is Signed URLs generated from the above code
public async Task<bool> UploadFile(byte[] data, Uri targetURL)
{
using (var request = new UnityWebRequest(targetURL, "PUT"))
{
request.uploadHandler = (UploadHandler)new UploadHandlerRaw(data);
request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
await request.SendWebRequest();
if (request.isNetworkError || request.isHttpError)
{
Debug.LogError(request.error);
Debug.LogError(request.downloadHandler.text);
return false;
}
else
{
Debug.Log("Upload complete!");
return true;
}
}
}
=== тестовый скрипт curl (CentOS7) ===
curl -X PUT --upload-file "[FilePath which I want to Upload to Firebase Storage]" "[Signed URLs]"