Конденсатор Firebase Firestore onSnapshot возвращает разрывы обещаний. Реагируйте на очистку useEffect с помощью «TypeErJavascript

Форум по Javascript
Ответить
Anonymous
 Конденсатор Firebase Firestore onSnapshot возвращает разрывы обещаний. Реагируйте на очистку useEffect с помощью «TypeEr

Сообщение Anonymous »

У меня есть приложение React, которое отлично работает в браузере, но когда я собираю его для iOS с помощью Capacitor, я постоянно получаю эту ошибку в минимизированном рабочем коде:

TypeError: e не является функцией.

Ошибка возникает при размонтировании компонента, когда React пытается вызвать возвращенную функцию очистки. Консоль показывает, что прослушиватель запускается нормально, но затем, когда компонент размонтируется, отображается ошибка.
Я использую прослушиватели реального времени Firebase Firestore для отображения обновлений данных в реальном времени в моем приложении. Проблема заключается в том, как плагин Firebase Capacitor обрабатывает функцию очистки onSnapshot. В React вы должны возвращать функцию очистки из useEffect Вот так:
useEffect(() => {
const unsubscribe = onSnapshot(query, (snapshot) => {
// handle data
});

return () => unsubscribe(); // cleanup when component unmounts
}, []);

Это отлично работает с обычным веб-SDK Firebase. Но плагин Capacitor Firebase (@capacitor-firebase/firestore) не возвращает функцию — он возвращает обещание, которое в конечном итоге дает вам идентификатор обратного вызова. Я пытался обернуть это так, чтобы React принял это, но что-то сломалось в процессе минификации.
Мой код оболочки
Вот что я пытался:
import { FirebaseFirestore } from '@capacitor-firebase/firestore';
import { onSnapshot as webOnSnapshot } from 'firebase/firestore';

export function onSnapshot(queryRef, callback, errorCallback) {
if (isCapacitor()) {
// This is where things get tricky...
const unsubscribeHolder = { callbackId: null, isUnsubscribed: false };

// Start the listener (this returns a Promise)
FirebaseFirestore.addCollectionSnapshotListener(
{
reference: queryRef._path,
compositeFilter: queryRef._compositeFilter
},
(event) => {
if (!unsubscribeHolder.isUnsubscribed) {
callback(processSnapshot(event));
}
}
).then(listener => {
// Store the callback ID for cleanup
unsubscribeHolder.callbackId = listener.callbackId;
}).catch(errorCallback);

// Return a function that uses the holder
return function() {
unsubscribeHolder.isUnsubscribed = true;
if (unsubscribeHolder.callbackId) {
FirebaseFirestore.removeSnapshotListener({
callbackId: unsubscribeHolder.callbackId
});
}
};
}

// Browser version works fine
return webOnSnapshot(queryRef, callback, errorCallback);
}

При разработке и производстве в режиме браузера все работает отлично. Но на iOS в режиме разработки: Listener запускается, но возникают ошибки очистки, а на рабочей версии iOS он полностью ломается с загадочной ошибкой TypeError: e не является ошибкой функции.
Ошибка возникает, когда компонент размонтируется и React пытается вызвать функцию очистки. Это похоже на то, что минификатор React делает что-то с кодом, который разрушает мост между обещанием и функцией, который я пытаюсь создать.
Я пробовал:
  • Синхронно возвращать функцию отписки (все еще прерывается после минификации)
  • Проверка typeof unsubscribe === 'function' перед ее вызовом (проверка проходит, но он по-прежнему ошибается!)
  • Несколько вариантов шаблона держателя
  • Различные оболочки обещаний
Я думаю, проблема в том, что addCollectionSnapshotListener Capacitor по своей сути является асинхронным (возвращает обещание), но useEffect React ожидает синхронного возврата функции. Когда React Scripts минимизирует все для производства, что-то в этом преобразовании нарушается, и я не могу отладить, потому что все минимизировано.
Мои вопросы:
  • Кто-нибудь действительно получил прослушиватели Firestore в реальном времени, работающие с Capacitor + React в производстве?
  • Есть ли правильный способ соединить асинхронный API Capacitor с Шаблон синхронной очистки React?
*Изменить:
Среда:
{
"@capacitor-firebase/firestore": "^7.3.1",
"@capacitor/core": "^7.4.3",
"firebase": "^11.2.0",
"react": "^19.0.0",
"react-scripts": "5.0.1"
}


Подробнее здесь: https://stackoverflow.com/questions/797 ... -useeffect
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»