我对于使用 Angular ionic 和 Firebase 进行严肃的应用程序开发还比较陌生。
我现在正在尝试弄清楚如何使用 Angular Fire 配置离线功能/无限缓存大小,持续了好几天 - 我完全迷失了!
我什至找不到一个很好的文档来说明这一点,这让我想知道这是否可能,尽管 Angular/Fire 中的很多现有 API 代码表明它应该在某种程度上是可能的。
到目前为止我能够实现的是使用disableNetwork()和enableNetwork()函数,这实际上导致从缓存加载数据。但这对我根本没有帮助 - 如果应用程序启动时没有网络连接 - 在这种情况下,我完全陷入了尝试加载第一部分的时间点来自 Firestore 的数据。另外,这也不是我需要的,因为它不会保留离线时所做的任何更改,这是 firebase 的核心功能(我不确定 Angular/fire 支持多少功能) .
我真的希望你们能帮助我,我很感激任何提示。
到目前为止我初始化 Firebase 的方式可以在下面的 conde 代码片段中看到。
我正在开发的独立角度应用程序的 main.ts: 请注意:没有代码尝试配置与离线存储/无限缓存相关的任何内容,因为我完全无能为力,到目前为止我尝试的一切都没有成功。
import { APP_INITIALIZER, enableProdMode, importProvidersFrom } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { RouteReuseStrategy, provideRouter } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { routes } from './app/app.routes';
import { AppComponent } from './app/app.component';
import { environment } from './environments/environment';
import { IonicStorageModule } from '@ionic/storage-angular';
import { Drivers } from '@ionic/storage';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { initializeApp, provideFirebaseApp } from '@angular/fire/app';
import { getAuth, provideAuth } from '@angular/fire/auth';
import { getAnalytics, provideAnalytics, ScreenTrackingService, UserTrackingService } from '@angular/fire/analytics';
import { getFirestore, provideFirestore, CACHE_SIZE_UNLIMITED, getPersistentCacheIndexManager, enablePersistentCacheIndexAutoCreation, PersistentLocalCache, Firestore } from '@angular/fire/firestore';
import { FirestoreDataService } from './app/firestoredata.service';
import { AuthService } from './app/services/auth.service';
import {Injectable, Inject } from '@angular/core';
if (environment.production) {
enableProdMode();
}
bootstrapApplication(AppComponent, {
providers: [
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
importProvidersFrom(
IonicModule.forRoot({}),
IonicStorageModule.forRoot({
driverOrder: [Drivers.IndexedDB, Drivers.LocalStorage],
}),
),
provideRouter(routes),
importProvidersFrom(HttpClientModule),
importProvidersFrom(TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: createTranslateLoader,
deps: [HttpClient]
}
})),
importProvidersFrom(provideFirebaseApp(() => initializeApp(environment.firebaseConfig))),
importProvidersFrom(provideAuth(() => getAuth())),
importProvidersFrom(provideAnalytics(() => getAnalytics())),
importProvidersFrom(provideFirestore(() => getFirestore())),
ScreenTrackingService, UserTrackingService,
{
provide: APP_INITIALIZER,
useFactory: () => initializeMyApp,
multi: true,
deps: [AuthService, FirestoreDataService, Firestore]
}
],
});
export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
经过多次用头撞最近的墙壁后,我终于想出了一个不太令人满意的解决方案,您可以在下面找到。我留在那儿的 FIXME 仍然是一些我非常感激能找到解决方案的东西..
import { APP_INITIALIZER, enableProdMode, importProvidersFrom } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { RouteReuseStrategy, provideRouter } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { routes } from './app/app.routes';
import { AppComponent } from './app/app.component';
import { environment } from './environments/environment';
import { IonicStorageModule } from '@ionic/storage-angular';
import { Drivers } from '@ionic/storage';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { FirebaseApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
import { getAuth, provideAuth } from '@angular/fire/auth';
import { getAnalytics, provideAnalytics, ScreenTrackingService, UserTrackingService } from '@angular/fire/analytics';
import { getFirestore, provideFirestore, PersistentCacheSettings, CACHE_SIZE_UNLIMITED, getPersistentCacheIndexManager, enablePersistentCacheIndexAutoCreation, PersistentLocalCache, Firestore, persistentLocalCache, initializeFirestore, FirestoreSettings, PersistentTabManager, persistentMultipleTabManager, enableIndexedDbPersistence } from '@angular/fire/firestore';
import { FirestoreDataService } from './app/firestoredata.service';
import { AuthService } from './app/services/auth.service';
import {Injectable, Inject } from '@angular/core';
if (environment.production) {
enableProdMode();
}
let fsapp: FirebaseApp ;
let fs: Firestore;
bootstrapApplication(AppComponent, {
providers: [
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
importProvidersFrom(
IonicModule.forRoot({}),
IonicStorageModule.forRoot({
driverOrder: [Drivers.IndexedDB, Drivers.LocalStorage],
}),
),
provideRouter(routes),
importProvidersFrom(HttpClientModule),
importProvidersFrom(TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: createTranslateLoader,
deps: [HttpClient]
}
})),
importProvidersFrom(provideFirebaseApp(() =>
{
fsapp = initializeApp(environment.firebaseConfig)
return fsapp
}
)),
{
provide: APP_INITIALIZER,
useFactory: () => initializeMyApp,
multi: true,
deps: []
},
importProvidersFrom(provideAuth(() => getAuth())),
importProvidersFrom(provideAnalytics(() => getAnalytics())),
importProvidersFrom(provideFirestore(() => fs)),
ScreenTrackingService,
UserTrackingService
],
});
export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
function initializeMyApp(): Promise<void> {
return new Promise<void>((resolve, reject) => {
console.log("initializeMyApp")
const plc = persistentLocalCache( {cacheSizeBytes: CACHE_SIZE_UNLIMITED, tabManager: persistentMultipleTabManager()} as PersistentCacheSettings ); //
initializeFirestore(fsapp, { cache: plc } as FirestoreSettings);
fs = getFirestore()
// FIXME in future: Not sure why the above code does not get the job done of this deprecated enableIndexedDbPersistence function...
enableIndexedDbPersistence(fs, { forceOwnership: !globalThis.localStorage }) // forceOwnership for web worker
.then(() => console.log("Offline persistence enabled"))
.catch(error => {
switch (error.code) {
case 'failed-precondition':
console.log("Offline persistence already enabled in another tab")
break
case 'unimplemented':
console.log("Offline persistence not supported by browser")
break
default:
console.error(error)
}
})
const im = getPersistentCacheIndexManager(fs)
if(im!=null){
enablePersistentCacheIndexAutoCreation(im);
}
resolve( )
});
}