Как исправить приложение Expo Android, которое не может выполнить более двух http-запросов подряд - PullRequest
0 голосов
/ 05 января 2019

У меня ужасная проблема, которая затрагивает только мое выставочное приложение на Android.

Я пытаюсь загрузить изображение base64, полученное с expo ImagePicker в Хранилище Firebase , передав значение изображения с помощью http-запроса, сделанного с axios, в Облачная функция Firebase который возвращает URL сохраненного изображения. Этот URL входит в Firestore , но я думаю, что это вне досягаемости моего вопроса.

Моя текущая реализация работает безупречно в IOS (я могу получить столько URL, сколько захочу, они загружаются довольно быстро), но в Android я могу загрузить только 2 изображения подряд; когда я пытаюсь в третий раз, мое приложение зависает, когда достигает оператора axios / fetch*, и не дает ни малейшего представления о том, что произошло. Консоль такая же, как была до попытки в третий раз, и приложения или симуляторы зависают.

Здесь вы можете увидеть это поведение в 2-минутном видео:

https://youtu.be/w66iXnKDmdo

Когда я начал работать над этой ошибкой, я использовал fetch вместо axios. В то время проблема заключалась в том, что мне удалось загрузить только одно изображение. Пришлось снова закрыть и открыть приложение, чтобы загрузить еще одно. Теперь с помощью axios я могу загрузить 2 блока из одного, но проблема остается.

Вот как я реализовал код:

const imageBase64 = 'QWEpqw0293k01...'

Вот как я загружаю изображение в Firebase Cloud Storage:

export const savePhoto = (imageBase64) => {
  const db = firebase.firestore();
  const docRef = db.collection('Comidas').doc();
  return () => {
    uploadImageToFirestore(imageBase64)
    .then(imageUrl => {
      console.log('image-url: ', imageUrl);
      docRef.set({ imagen: { uri: imageUrl }, });
    })
    .catch(err => console.log('error: ', err));
  };
};

Я сделал функцию-помощник, позволяющую сделать http-запрос многоразовым:

import axios from 'axios';

export const uploadImageToFirestore = (imageBase64) => {
//<--- here is where it get frozen the third time
//<--- console.log() calls three times but not axios
  return axios({
    method: 'post',
    url: 'https://us-central1-menuapp-9feb4.cloudfunctions.net/almacenamientoImagen',
    data: {
      image: base64
    },
  })
  .then(res => res.data.imageUrl)
  .catch(err => console.log('error while uploading base64: ', err));
};

Это вызывает следующую облачную функцию Firebase:

exports = module.exports = functions.https.onRequest((req, res) => {
  cors(req, res, () => {
    const body = req.body;
    console.log('image: ', body.image);
    fs.writeFileSync("/tmp/uploaded-image.jpg", body.image, "base64", err => {
  console.log(err);
  return res.status(500).json({ error: err });
});
const bucket = gcs.bucket("myapp.appspot.com");
const uuid = UUID();

bucket.upload(
  "/tmp/uploaded-image.jpg",
  {
    uploadType: "media",
    destination: "/comidas/" + uuid + ".jpg",
    metadata: {
      metadata: {
        contentType: "image/jpeg",
        firebaseStorageDownloadTokens: uuid
      }
    }
  },
  (err, file) => {
    if (!err) {
      console.log('url: ', {
        imageUrl:
          "https://firebasestorage.googleapis.com/v0/b/" +
          bucket.name +
          "/o/" +
          encodeURIComponent(file.name) +
          "?alt=media&token=" +
          uuid
      });

      res.status(201).json({
        imageUrl:
          "https://firebasestorage.googleapis.com/v0/b/" +
          bucket.name +
          "/o/" +
          encodeURIComponent(file.name) +
          "?alt=media&token=" +
          uuid
      });
    } else {
      console.log(err);
      res.status(500).json({ error: err });
    }
  }
  );
 });
});

Я знаю, что его не вызывают, потому что нет ни журнала, ни регистра выполнения функции Firebase Cloud.

Я ожидаю, что этот код будет загружать столько изображений, сколько пользователь посчитает нужным ему, а не только 2 за сеанс приложения, как это происходит в данный момент

Как я могу решить эту проблему?

...