У меня ужасная проблема, которая затрагивает только мое выставочное приложение на 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 за сеанс приложения, как это происходит в данный момент
Как я могу решить эту проблему?