firebase / firebase-js-sdk

Firebase Javascript SDK
https://firebase.google.com/docs/web/setup
Other
4.81k stars 884 forks source link

AngularFireDatabase works on web and android but not ios #3403 #7407

Open drkhannah opened 1 year ago

drkhannah commented 1 year ago

Operating System

iOS 16.5

Browser Version

chrome

Firebase SDK Version

"firebase": "^9.23.0",

Firebase SDK Product:

Database

Describe your project's tooling

Ionic app using Angular

Describe the problem

https://github.com/angular/angularfire/issues/3403

**im using AngularFireDatabase to connect to my realtime database

this works fine on Android and Web, but not on ios

on ios i get this error**

[Error] TypeError: undefined is not an object (evaluating 'gapi.iframes.getContext') callback (main.cb86b0cb1b1543a2.js:1:156205) (anonymous function) (api.js:29) Ja (api.js:21:705) E (api.js:28:502) (anonymous function) (api.js:29:83) (anonymous function) (api.js:29:146) Global Code (cb=gapi.loaded_0:1) [Error] Error: A`capacitor (anonymous function) (api.js:29:638) (anonymous function) (api.js:29) Ja (api.js:21:705) E (api.js:28:502) (anonymous function) (api.js:29:83) (anonymous function) (api.js:29:146) Global Code (cb=gapi.loaded1:1) [Error] Cross-origin redirection to http://developers.google.com/ denied by Cross-Origin Resource Sharing policy: Origin capacitor://localhost is not allowed by Access-Control-Allow-Origin. Status code: 301 [Error] XMLHttpRequest cannot load https://apis.google.com//jserror?script=https%3A%2F%2Fapis.google.com%2F%2Fscs%2Fabc-static%2F%2Fjs%2Fk%3Dgapi.lb.en.5o5-TAFr18s.O%2Fm%3Dgapi_iframes%2Frt%3Dj%2Fsv%3D1%2Fd%3D1%2Fed%3D1%2Frs%3DAHpOoo_qgszOsFrBH7bZ1Rmfwa9Mc03wLQ%2Fcb%3Dgapi.loaded_0&error=A%60capacitor&line=150 due to access control checks. [Error] Failed to load resource: Cross-origin redirection to http://developers.google.com/ denied by Cross-Origin Resource Sharing policy: Origin capacitor://localhost is not allowed by Access-Control-Allow-Origin. Status code: 301 (jserror, line 0)

Here is my app module code

import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { RouteReuseStrategy } from '@angular/router'; import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { HttpClientModule } from '@angular/common/http' import { initializeApp, provideFirebaseApp } from '@angular/fire/app' import { getFirestore, provideFirestore } from '@angular/fire/firestore' import { environment } from '../environments/environment'; import { provideAnalytics, getAnalytics, ScreenTrackingService, UserTrackingService } from '@angular/fire/analytics'; import { provideDatabase, getDatabase } from '@angular/fire/database' import { getAuth, provideAuth } from '@angular/fire/auth' import { FIREBASE_OPTIONS } from '@angular/fire/compat'

@NgModule({ declarations: [AppComponent], imports: [ BrowserModule, IonicModule.forRoot(), AppRoutingModule, HttpClientModule, provideFirebaseApp(() => initializeApp(environment.firebaseConfig)), provideFirestore(() => getFirestore()), provideAnalytics(() => getAnalytics()), provideDatabase(() => getDatabase()), provideAuth(() => getAuth()), ], providers: [ {provide: RouteReuseStrategy, useClass: IonicRouteStrategy}, {provide: FIREBASE_OPTIONS, useValue: environment.firebaseConfig}, ScreenTrackingService, UserTrackingService ], bootstrap: [AppComponent], }) export class AppModule { }

here is my package.json

{ "name": "seasonal-simple", "version": "0.0.1", "author": "Ionic Framework", "homepage": "https://ionicframework.com/", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "watch": "ng build --watch --configuration development", "test": "ng test", "lint": "ng lint" }, "private": true, "dependencies": { "@angular/animations": "^16.0.0", "@angular/common": "^16.0.0", "@angular/compiler": "^16.0.0", "@angular/core": "^16.0.0", "@angular/fire": "^7.6.1", "@angular/forms": "^16.0.0", "@angular/platform-browser": "^16.0.0", "@angular/platform-browser-dynamic": "^16.0.0", "@angular/router": "^16.0.0", "@capacitor/android": "5.0.2", "@capacitor/app": "^5.0.2", "@capacitor/core": "5.0.2", "@capacitor/haptics": "^5.0.2", "@capacitor/ios": "5.0.2", "@capacitor/keyboard": "^5.0.2", "@capacitor/status-bar": "^5.0.2", "@ionic/angular": "^7.0.0", "firebase": "^9.23.0", "ionicons": "^7.0.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", "vite": "^4.3.9", "zone.js": "~0.13.0" }, "devDependencies": { "@angular-devkit/build-angular": "^16.0.0", "@angular-eslint/builder": "^16.0.0", "@angular-eslint/eslint-plugin": "^16.0.0", "@angular-eslint/eslint-plugin-template": "^16.0.0", "@angular-eslint/schematics": "^16.0.0", "@angular-eslint/template-parser": "^16.0.0", "@angular/cli": "^16.0.0", "@angular/compiler": "^16.0.0", "@angular/compiler-cli": "^16.0.0", "@angular/language-service": "^16.0.0", "@capacitor/assets": "^2.0.4", "@capacitor/cli": "5.0.2", "@ionic/angular-toolkit": "^9.0.0", "@types/jasmine": "~4.3.0", "@types/node": "^12.11.1", "@typescript-eslint/eslint-plugin": "5.3.0", "@typescript-eslint/parser": "5.3.0", "capacitor-set-version": "^2.0.13", "eslint": "^7.26.0", "eslint-plugin-import": "2.22.1", "eslint-plugin-jsdoc": "30.7.6", "eslint-plugin-prefer-arrow": "1.2.2", "jasmine-core": "~4.6.0", "jasmine-spec-reporter": "~5.0.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.2.0", "karma-coverage": "~2.2.0", "karma-coverage-istanbul-reporter": "~3.0.2", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.0.0", "ts-node": "^8.3.0", "typescript": "~5.0.2" }, "description": "An Ionic project" }

Steps and code to reproduce issue

get data from realtime database, works in browsers and on android, does not work on ios

vishal-revdiwala commented 1 year ago

I'm also experiencing the exact same issue, but only on iPad. It's working fine on Android and iPhone devices.

@google-oss-bot Any fix or workaround?

dodomui commented 1 year ago

I'm having same issue. basically, all firebase functions not works on iOS devices. But it working just fine on android and web. Below is my environment. Ionic:

Ionic CLI : 7.1.1 (/usr/local/lib/node_modules/@ionic/cli) Ionic Framework : @ionic/angular 7.2.0 @angular-devkit/build-angular : 16.1.5 @angular-devkit/schematics : 16.1.5 @angular/cli : 16.1.5 @ionic/angular-toolkit : 10.0.0

Capacitor:

Capacitor CLI : 5.2.2 @capacitor/android : 5.2.2 @capacitor/core : 5.2.2 @capacitor/ios : 5.2.2

Utility:

cordova-res : not installed globally native-run : 1.7.2

System:

NodeJS : v18.12.1 (/usr/local/bin/node) npm : 9.8.1 OS : macOS Unknown

"@angular/fire": "^7.6.1", "firebase": "^9.23.0",

drkhannah commented 1 year ago

This lib doesn’t work on iOS, rip it out and just hit the database https urls with a normal angular http network call, that’s what I had to do

dodomui commented 1 year ago

@drkhannah my is working just fine with exactly same version by using compat web SDK. Many issue happens after I changed to modular SDK. So ends up my iOS is not working again.

vishal-revdiwala commented 1 year ago

Guys, now I am able to get this working flawlessly. The solution involved uninstalling the '@angular/fire' node modules and instead using only the Firebase JavaScript SDK. The initialization process for both authentication and the database was done as follows:

`import { initializeApp } from 'firebase/app'; import { Auth, getAuth, indexedDBLocalPersistence, initializeAuth, signInWithCustomToken } from 'firebase/auth'; import { Database, getDatabase } from 'firebase/database';

// Define class properties for database and authentication private readonly database: Database; private readonly auth: Auth;

constructor() { // Initialize Firebase app with environment.firebaseProps configuration const firebaseApp = initializeApp(environment.firebaseProps);

// Initialize Firebase authentication with indexedDBLocalPersistence initializeAuth(firebaseApp, { persistence: indexedDBLocalPersistence });

// Get a reference to the Firebase database and authentication instance this.database = getDatabase(firebaseApp); this.auth = getAuth(firebaseApp); } `

dodomui commented 1 year ago

@vishal-revdiwala there's lots of changes needed if change from Angularfire to Javascript SDK. All the firebase related features need to be start after initialize firebase app from app component.

My program is huge. Still wondering should I changed back compat SDK or not. It's working just fine to me while using compat SDK with exactly same angularfire and firebase version.

maneesht commented 1 year ago

This looks like a duplicate of #5019

rostislavcz commented 1 month ago

Gosh, took me about an hour to solve that even with @angular/fire package

TL:DR if (Capacitor.isNativePlatform() && !isPlatform('android')) { auth = initializeAuth(app); } else { auth = getAuth() }

constructor( private app: FirebaseApp, ) { }

AND IMPORTANT, if you want to create app with different name, I did it with:

const app = initializeApp(firebaseConfig, 'realtimedb');

but important, even though you must set private app: FirebaseApp, in your constructor, othwrwise you get an error.. something about that you cannot initialize an app out of an angular module or something like that, but if you just inject that dependency, you can then freely call initializeApp()