Comments (5)
This issue does not seem to follow the issue template. Make sure you provide all the required information.
from angularfire.
Very little information to deduce the problem. Please upload a part of your project on stackblitz where we can reproduce this issue. Or if possible please share a github repository.
from angularfire.
@Sapython - The initialization part is very generic which anyone would do normally. It's been shared in the description. Apart from this, I have a lazyLoad service file that would be invoked with the required parameters every time on different components.
Please find the contents of the file below.
//// This Service would be a non singleton instance since it is used by multiple list modules and data has to be fresh for each module
//// Hence, its not provided through Service module, but rather its provided through individual list components
import { Injectable, OnDestroy } from "@angular/core";
import {
AngularFirestore,
DocumentSnapshot,
Query,
} from "@angular/fire/compat/firestore";
import { WhereFilterOp } from "@firebase/firestore-types";
import { Subject } from "rxjs";
import { takeUntil, auditTime, map } from "rxjs/operators";
import * as firebase from "firebase/compat/app";
import { NgxSpinnerService } from "ngx-spinner";
@Injectable({
providedIn: "root",
})
export class LazyloadService<T> implements OnDestroy {
tableData: T[] = [];
where: { key: string; op: WhereFilterOp; value: string | string[] }[] | null =
[];
limit = 10;
collection = "";
dataLoading = false;
doneLoading = false;
spinnerName = "pageLoader";
// save last document in snapshot of items received
private lastInResponse: DocumentSnapshot<T> | any;
// keep the array of first document of previous pages
private prev_strt_at: DocumentSnapshot<T>[] = [];
subs$: Subject<void> = new Subject<void>();
constructor(
private afs: AngularFirestore,
private spinnerService: NgxSpinnerService
) {}
loadItems({ isReset = false, isNext = false }) {
if (isReset) {
this.dataLoading = false;
this.doneLoading = false;
this.tableData = [];
this.spinnerName = "pageLoader";
}
if (this.doneLoading) {
this.spinnerService.hide("pageLoader");
this.spinnerService.hide("contentLoader");
}
if (this.dataLoading || this.doneLoading) {
return;
}
this.spinnerService.show(this.spinnerName);
this.dataLoading = true;
return this.afs
.collection(this.collection, (ref) => this.createQueryRef(ref, isNext))
.snapshotChanges()
.pipe(
takeUntil(this.subs$),
auditTime(1000),
map((response) => {
this.doneLoading = response.length === 0;
this.spinnerService.hide(this.spinnerName);
this.lastInResponse = response[response?.length - 1]?.payload.doc;
this.push_prev_startAt(this.lastInResponse);
response.forEach((record) => {
// Avoid pushing duplicates
if (
this.tableData.filter(
(item: any) => item["id"] === record?.payload.doc.id
).length <= 0
) {
this.tableData.push({
...(record?.payload.doc.data() as T),
id: record?.payload.doc.id,
});
}
});
this.dataLoading = false;
return;
})
);
}
private createQueryRef(ref: any, isNext: boolean): Query {
let queryRef: Query = ref;
let orderByKey: any = "modifiedDate";
let order: any = "desc";
if (this.where) {
this.where.forEach((condition, index) => {
const { orderByKeyVal, orderVal, queryRefVal } = this.updateQueryRef(
condition,
index,
orderByKey,
order,
queryRef
);
queryRef = queryRefVal;
orderByKey = orderByKeyVal;
order = orderVal;
});
}
queryRef = queryRef.limit(this.limit);
if (orderByKey !== "date") {
queryRef = queryRef.orderBy(orderByKey, order);
}
if (isNext && this.lastInResponse) {
queryRef = queryRef.startAfter(this.lastInResponse);
}
return queryRef;
}
private updateQueryRef(
condition: { key: string; op: WhereFilterOp; value: string | string[] },
index: number,
orderByKey: any,
order: any,
queryRef: Query
): { orderByKeyVal: any; orderVal: any; queryRefVal: Query } {
const key =
condition.key === "id"
? firebase.default.firestore.FieldPath.documentId()
: condition.key;
if (index === 0 && !condition.key?.includes(".")) {
orderByKey = key;
order = condition.key === "id" ? "asc" : "desc";
} else if (condition.key?.includes(".")) {
orderByKey = firebase.default.firestore.FieldPath.documentId();
}
if (condition.value instanceof Array) {
condition.value = condition.value.splice(0, 10);
}
queryRef = queryRef.where(key, condition?.op, condition?.value);
return {
orderByKeyVal: orderByKey,
orderVal: order,
queryRefVal: queryRef,
};
}
push_prev_startAt(prev_first_doc: DocumentSnapshot<T>) {
this.prev_strt_at.push(prev_first_doc);
}
ngOnDestroy() {
this.subs$.next();
this.subs$.complete();
}
}
Unfortunately, I would not be able to create a stack blitz project because of the complexity and unable to share access to the project because of the confidentiality.
from angularfire.
Ok, nothing here seems, that can cause connection issue.
I have a suggestions
- Comment all the modules of your app in
app.module.ts
- Turn it into a blank app by commenting every route in app.routing
- Comment every imported module created by you in
app.module.ts
- Comment every module of Firebase except
provideFirestore
andinitializeApp
inapp.module.ts
- Then call a simple
getDoc
request inside the app.component.ts
Check if Firebase is working.
- If yes then the issue has to do with this service or the project itself
- but if it fails then it means Firebase is the issue.
from angularfire.
Finally, after much digging around the internet, I've resolved this issue by the below steps. However, I was not able to find the root cause for the same.
My application uses a combination of modular v9 library and compatibility library for a few functionalities. This is where I had to use the initialization features of the application for both modular and compatibility libraries. I presume this could have been one of the reasons for the issue. Based on this presumption, I eliminated the dependency on the compatibility libraries and started using modular v9 features.
My code now looks like the below:
app.module.ts
import { APP_ID, NgModule } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { BrowserModule } from "@angular/platform-browser";
import { RouterModule } from "@angular/router";
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
import { SharedModule } from "./shared/shared.module";
import { CoreModule } from "./core/core.module";
// Firebase/Firestore
import { getApp, initializeApp, provideFirebaseApp } from "@angular/fire/app";
import { provideAuth, getAuth, connectAuthEmulator } from "@angular/fire/auth";
import {
initializeAppCheck,
provideAppCheck,
ReCaptchaEnterpriseProvider,
} from "@angular/fire/app-check";
import {
initializeFirestore,
persistentLocalCache,
persistentMultipleTabManager,
provideFirestore,
connectFirestoreEmulator,
Firestore,
getFirestore,
} from "@angular/fire/firestore";
import { environment } from "src/environments/environment";
import { NgxSpinnerModule } from "ngx-spinner";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import {
getAnalytics,
provideAnalytics,
ScreenTrackingService,
UserTrackingService,
} from "@angular/fire/analytics";
import { getPerformance, providePerformance } from "@angular/fire/performance";
import { LocationStrategy, PathLocationStrategy } from "@angular/common";
import { FullCalendarModule } from "@fullcalendar/angular"; // must go before plugins
declare global {
// eslint-disable-next-line no-var
var FIREBASE_APPCHECK_DEBUG_TOKEN: boolean | string | undefined;
}
if (!environment.production) {
self.FIREBASE_APPCHECK_DEBUG_TOKEN = environment.appCheckDebug; // set to <debugToken> that registered with App-Check in Firebase Console
}
@NgModule({
declarations: [AppComponent],
imports: [
BrowserAnimationsModule,
BrowserModule,
NgbModule,
FormsModule,
RouterModule,
AppRoutingModule,
SharedModule,
CoreModule,
NgxSpinnerModule,
FullCalendarModule,
provideFirebaseApp(() => initializeApp(environment.firebaseConfig)),
provideFirestore(() => {
let firestore: Firestore;
if (!environment.production) {
firestore = getFirestore(getApp());
connectFirestoreEmulator(firestore, "localhost", 8089);
} else {
firestore = initializeFirestore(getApp(), {
localCache: persistentLocalCache({
tabManager: persistentMultipleTabManager(),
}),
experimentalAutoDetectLongPolling: true,
experimentalLongPollingOptions: {
timeoutSeconds: 30,
},
});
}
return firestore;
}),
provideAuth(() => {
const auth = getAuth();
if (!environment.production) {
connectAuthEmulator(auth, "http://localhost:9099", {
disableWarnings: true,
});
}
return auth;
}),
providePerformance(() => getPerformance(getApp())),
provideAppCheck(() =>
initializeAppCheck(getApp(), {
provider: new ReCaptchaEnterpriseProvider(environment.recaptchaSiteKey),
isTokenAutoRefreshEnabled: true,
})
),
provideAnalytics(() => getAnalytics(getApp())),
],
providers: [
ScreenTrackingService,
UserTrackingService,
{ provide: LocationStrategy, useClass: PathLocationStrategy },
{
provide: APP_ID,
useValue: "serverApp",
},
],
bootstrap: [AppComponent],
})
export class AppModule {}
lazyload.service.ts
//// This Service would be a non singleton instance since it is used by multiple list modules and data has to be fresh for each module
//// Hence, its not provided through Service module, but rather its provided through individual list components
import { Injectable, OnDestroy, inject } from "@angular/core";
import { WhereFilterOp } from "@firebase/firestore-types";
import { Subject } from "rxjs";
import { takeUntil, map } from "rxjs/operators";
import { NgxSpinnerService } from "ngx-spinner";
import {
collection,
query,
Query,
where,
documentId,
orderBy,
limit,
startAfter,
DocumentSnapshot,
CollectionReference,
collectionSnapshots,
Firestore,
} from "@angular/fire/firestore";
import { traceUntilFirst } from "@angular/fire/performance";
@Injectable({
providedIn: "any",
})
export class LazyloadService<T> implements OnDestroy {
tableData: T[] = [];
where: { key: string; op: WhereFilterOp; value: string | string[] }[] | null =
[];
limit = 10;
collection = "";
dataLoading = false;
doneLoading = false;
spinnerName = "pageLoader";
// save last document in snapshot of items received
private lastInResponse: DocumentSnapshot<T> | any;
// keep the array of first document of previous pages
private prev_strt_at: DocumentSnapshot<T>[] = [];
subs$: Subject<void> = new Subject<void>();
private firestore: Firestore = inject(Firestore);
private spinnerService: NgxSpinnerService = inject(NgxSpinnerService);
loadItems({ isReset = false, isNext = false }) {
if (isReset) {
this.dataLoading = false;
this.doneLoading = false;
this.tableData = [];
this.spinnerName = "pageLoader";
}
if (this.doneLoading) {
this.spinnerService.hide("pageLoader");
this.spinnerService.hide("contentLoader");
}
if (this.dataLoading || this.doneLoading) {
return;
}
this.spinnerService.show(this.spinnerName);
this.dataLoading = true;
const collectionRef = collection(this.firestore, this.collection);
const q = this.createQueryRef(collectionRef, isNext);
return collectionSnapshots(q).pipe(
traceUntilFirst(this.collection),
takeUntil(this.subs$),
map((response) => {
this.doneLoading = response.length === 0;
this.spinnerService.hide(this.spinnerName);
this.lastInResponse = response[response?.length - 1];
this.push_prev_startAt(this.lastInResponse);
response.forEach((record) => {
// Avoid pushing duplicates
if (
this.tableData.filter((item: any) => item["id"] === record?.id)
.length <= 0
) {
this.tableData.push({
...(record?.data() as T),
id: record?.id,
});
}
});
this.dataLoading = false;
return;
})
);
}
private createQueryRef(ref: CollectionReference, isNext: boolean): Query {
let queryRef: Query;
let orderByKey: any = "modifiedDate";
let order: any = "desc";
const conditions: any = [];
if (this.where) {
this.where.forEach((condition, index) => {
const key = condition.key === "id" ? documentId() : condition.key;
if (index === 0 && !condition.key?.includes(".")) {
orderByKey = key;
order = condition.key === "id" ? "asc" : "desc";
} else if (condition.key?.includes(".")) {
orderByKey = documentId();
}
if (condition.value instanceof Array) {
condition.value = condition.value.splice(0, 10);
}
conditions.push(where(key, condition?.op, condition?.value));
});
}
conditions.push(limit(this.limit));
if (orderByKey !== "date") {
conditions.push(orderBy(orderByKey, order));
}
if (isNext && this.lastInResponse) {
conditions.push(startAfter(this.lastInResponse));
}
queryRef = query(ref, ...conditions);
return queryRef;
}
push_prev_startAt(prev_first_doc: DocumentSnapshot<T>) {
this.prev_strt_at.push(prev_first_doc);
}
ngOnDestroy() {
this.subs$.next();
this.subs$.complete();
}
}
However, even after the above changes, I was getting the same behavior, which when further inspected, I noticed many of them were using @angular/[email protected]
and I was using @angular/[email protected]
. I went ahead and downgraded to the v7.x version, which is when I started getting a different issue before I could validate the actual issue.
ERROR FirebaseError: Expected type 'Query', but it was: a custom dh object
One of the suggestions was to downgrade the Firebase version as well to v9, which I followed. This, however, ended up resolving the issue but created one more issue which was related to the version of rxfire
library used by angular/[email protected]
.
Ultimately, I had to override the rxfire
version for angular/fire
like below and I was successfully able to resolve the actual issue I had.
"overrides": {
"@angular/fire@^7.6.1": {
"rxfire@^6.0.0": "6.0.3"
}
}
I'm still not sure if this was a problem with @angular/[email protected]
. I did not dare to test this with @angular/[email protected]
as I had lost many days digging around resolving the issue.
Hope this helps someone.
from angularfire.
Related Issues (20)
- feat: allow AngularFire to be used in a zoneless angular application HOT 14
- reauthenticateWithPhoneNumber throws auth/user-mismatch error HOT 1
- collectionData doesn't allow angular app to become stable with angular 17 and ssr (getDocs does) HOT 2
- Profile CRUD
- [BUG] optimization: true cause Service functions is not available Error: Service functions is not available
- @ngx-env/builder:application is not a recognized builder HOT 4
- Deployment to Google Cloud Run using Angular v17 Application Builder not working
- [error] AssertionError [ERR_ASSERTION]: catch clause variable is not an Error instance HOT 2
- Appcheck on Angular 17 does not work! HOT 3
- How to tell FCM to load the firebase-messaging-sw file in a different call route(href)? in @angular/fire (FCM) HOT 1
- where is firestore.fieldValue? HOT 1
- After updating angular cli and angular core to 15, I'm getting error in firebase as no firebase app default has been created HOT 1
- serverTimestamp fails when uploading to firestore. HOT 2
- Can't set custom lang to email templates HOT 2
- Unhandled Promise rejection Analytics with SSR HOT 1
- [Android] Firestore snapshot listeners is slow to retrieve data.
- Compat sample does not compile
- Either AngularFireModule has not been provided in your AppModule HOT 1
- [Angular 15 + Firebase 7] Build in production mode error: Component auth has not been registered yet HOT 1
- Unable to load dynamic firebase config, tried many ways but fail to load. HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from angularfire.