Если вы попытаетесь отправить файл с помощью запроса Unity WebRequest / Put на URL загрузки с подписью, созданной с помощью функции Firebase, произойдет сбой - PullRequest
0 голосов
/ 04 мая 2020

Что я хочу сделать
Использование класса 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]"

...