angular/fire docData works on chrome/safari macos but never emits on capacitor-ios

the angular/fire method docData works on chrome/safari macos but never emits on capacitor-ios (capacitor uses webkit-safari on ios)

I can see that the game-object is really exisiting since it shows up & emtis on my desktop browsers and I am even able to interact with this object on my capacitor-ios-native-app but just not able to receive any stream updates. The game doc ref console log correclty logs the game too, so the error really needs to lie inside the docData function (?)

All other operations like reading/writing/deleting (without streams) work on ios.

Any hints for debugging would be much appreciated.

Here is my code, remember that this works perfectly on desktop.

const gameDocRef = doc(this.firestore, 'game', game.id);
if (showGameLogs) {
  let toLog: any = (gameDocRef as any)._key;
  console.log("gameDocRef:", gameDocRef);
  console.log("🟩 CALLING DOC_DATA ON THIS GAME DOC REF:", toLog?.path?.segments);
}
const game$ = docData(gameDocRef, { idField: 'id' }).pipe(
  map(data => {
    if (showGameLogs) {
      console.log("🟩 docData EMISSION:", data);
    }
    if (data === undefined) {
      return null;
    } else {
      return data;
    }
  })
) as Observable<Game | null>;

I inspected the network activity before docData gets called on ios and it happens that nothing happens at all, there is no stream created or so:

comparing to the network logs I get on my chrome macbook, there IS indeed network requests happening, with “channel”:

Also do note that there is a custom capacitor plugin for firestore but it does not have a function like docData that would return an observable. It only has a function that does this with a callback approach. And the plugin is not widely used so I would prefer to stick to the more popular angular/fire library.

A minimum reproducible example for capacitor-ios would be hard to create for me and hard to test for you of course, but I will create one as soon as someone answered my other minimiumum reproducible example question (see my accounts last question).

update:

I wrote my own custom docData function with the bare Web-modular-api and it still does not create a channel on ios native capacitor (but works perfectly on desktop chrome/safari):

import { onSnapshot } from "firebase/firestore";

function docData<T>(docRef: DocumentReference<T>, options?: { idField?: string }): Observable<T> {
  return new Observable<T>(observer => {
    const unsubscribe = onSnapshot(docRef,
      (docSnapshot) => {
        if (docSnapshot.exists()) {
          const data = docSnapshot.data() as T;
          if (options?.idField) {
            (data as any)[options.idField] = docSnapshot.id;
          }
          observer.next(data);
        } else {
          observer.next(undefined as any);
        }
      },
      (error) => {
        console.error("Error fetching document:", error);
        observer.error(error);
      }
    );
    return { unsubscribe };
  });
}

even doing this does not do anything, but only on capacitor-ios (it DOES log ALWAYS on desktop safari/chrome):

onSnapshot(gameDocRef, () => console.log("EMISSION DETECTED"));

why does this not create a channel, even though I can clearly calling onSnapshot? Is this a bug inside the firebase/firestore web sdk onSnapshot method?

I ended up using this plugin which solves it on capacitor-ios:

https://github.com/capawesome-team/capacitor-firebase/tree/main/packages/firestore

Note that this library does not solve the underlying issue but instead it uses the native IOS/Android APIs from firebase, which also come with performance improvements. Read more here:

https://capawesome.io/blog/announcing-the-capacitor-firebase-cloud-firestore-plugin/

This is how I am using this plugin, to mimic the angular/fire docData function to return an observable. I tried to get the same API as the Angular docData function. But use the below code with caution as I did not test it thorougly:

import {
  AddDocumentSnapshotListenerCallback,
  AddDocumentSnapshotListenerOptions,
  CallbackId, DocumentData,
  FirebaseFirestore, RemoveSnapshotListenerOptions
} from '@capacitor-firebase/firestore';

function docData<T extends DocumentData>(docRef: DocumentReference<T>, options?: { idField?: string }): Observable<T | null> {
  return new Observable<T | null>(observer => {
    let callbackId: CallbackId;

    const listenerOptions: AddDocumentSnapshotListenerOptions = {
      reference: docRef.path
    };

    const callback: AddDocumentSnapshotListenerCallback<T> = (event, error) => {
      if (error) {
        console.error("Error fetching document:", error);
        observer.error(error);
        return;
      }

      if (event && event.snapshot) {
        const data = event.snapshot.data;
        if (data && options?.idField) {
          try {
            (data as any)[options.idField] = event.snapshot.id || null;
          } catch (e) {
            console.error("Error setting idField:", e);
          }
        }
        observer.next(data || null);
      } else {
        observer.next(null);
      }
    };

    FirebaseFirestore.addDocumentSnapshotListener(listenerOptions, callback)
      .then(id => callbackId = id)
      .catch(error => observer.error(error));

    return {
      unsubscribe: () => {
        if (callbackId) {
          const removeOptions: RemoveSnapshotListenerOptions = { callbackId };
          FirebaseFirestore.removeSnapshotListener(removeOptions)
            .catch(error => console.error("Error removing listener:", error));
        }
      }
    };
  });
}

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật