如何使用 @angular/fire 17 和 ionic @ionic/Angular 7.6.2 配置 firestore 以完全离线工作?

问题描述 投票:0回答:1

我对于使用 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');
}
android angular firebase ionic-framework google-cloud-firestore
1个回答
0
投票

经过多次用头撞最近的墙壁后,我终于想出了一个不太令人满意的解决方案,您可以在下面找到。我留在那儿的 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( )

  });
}
© www.soinside.com 2019 - 2024. All rights reserved.