NativeScript / firebase

Modular Firebase πŸ”₯ implementation for NativeScript. Supports both iOS & Android platforms for all Firebase services.
https://docs.nativescript.org/plugins/firebase-core.html
Apache License 2.0
55 stars 49 forks source link

initializeApp not working on iOS device #166

Open ajveach opened 1 year ago

ajveach commented 1 year ago

I'm converting an app from the old @nativescript/firebase library, and this is just about complete and fully functional on Android. I just tried running this on iOS, and the app is not initializing properly. In looking through firebase-core/index.ios.js, I've discovered that my initialization request is being added to the launchQueue array, but launchCallback is never being called.

There are no errors shown in the logs, so from what I can see the issue is just that this launchQueue is never being used.

I have the same GoogleService-Info.plist file as before in App_Resources/iOS. These are the relevant parts of the main.js file that's acting as the entry point:

import { firebase } from '@nativescript/firebase-core'
import '@nativescript/firebase-auth';
import '@nativescript/firebase-crashlytics';
import '@nativescript/firebase-analytics';
import '@nativescript/firebase-messaging';

// Initialize Firebase
firebase().initializeApp().then(() => {
  console.warn('πŸ”₯ Firebase initialized');
}).catch(error => {
  console.error('πŸ”₯ Firebase initialization error: ', error)
});

If I log to the console right before firebase().initializeApp() on iOS I see the log, but the 'Firebase initialized' log never appears. Adding additional logs in firebase-core/index.ios.js shows me that UIApplication.sharedApplication is null when checked, so the call to initApp is appended to the launchQueue array and then never used.

triniwiz commented 1 year ago

Can you try pinning the version to 2.4.4

ajveach commented 1 year ago

Thanks for the response! I just tried updating all the @nativescript/firebase-* dependencies to 2.4.4. This is the full list of dependencies now:

{
"dependencies": {
    "@cloudinary/url-gen": "^1.8.0",
    "@nativescript-community/ui-material-bottom-navigation": "^7.0.3",
    "@nativescript/camera": "^5.0.13",
    "@nativescript/core": "8.3.5",
    "@nativescript/directions": "^2.0.0",
    "@nativescript/firebase-analytics": "2.4.4",
    "@nativescript/firebase-auth": "2.4.4",
    "@nativescript/firebase-core": "2.4.4",
    "@nativescript/firebase-crashlytics": "2.4.4",
    "@nativescript/firebase-messaging": "2.4.4",
    "@nativescript/firebase-performance": "2.4.4",
    "@nativescript/imagepicker": "^1.0.6",
    "@nativescript/iqkeyboardmanager": "^2.0.0",
    "@nativescript/local-notifications": "^6.0.0",
    "@nstudio/nativescript-cardview": "^2.0.1",
    "@nstudio/nativescript-fancyalert": "^4.0.0",
    "@nstudio/nativescript-pulltorefresh": "^3.0.1",
    "@triniwiz/nativescript-socketio": "^5.0.1",
    "@triniwiz/nativescript-toasty": "^4.1.3",
    "@vue/devtools": "^5.3.4",
    "assert": "^2.0.0",
    "axios": "^0.21.1",
    "browserify-zlib": "^0.2.0",
    "buffer": "^6.0.3",
    "cloudinary": "^1.30.0",
    "crypto-browserify": "^3.12.0",
    "electron": "^21.0.1",
    "email-validator": "^2.0.4",
    "file-system": "^2.2.2",
    "https-browserify": "^1.0.0",
    "moment": "^2.24.0",
    "nativescript-calendar": "^3.0.0",
    "nativescript-camera": "^4.5.0",
    "nativescript-carousel": "^7.0.1",
    "nativescript-directions": "^1.4.0",
    "nativescript-email": "^1.6.0",
    "nativescript-feedback": "^2.0.0",
    "nativescript-gif": "^5.0.0",
    "nativescript-http-formdata": "^3.1.1",
    "nativescript-phone": "^2.0.0",
    "nativescript-sentry": "^2.0.1",
    "nativescript-toasty": "^3.0.0-alpha.2",
    "nativescript-vue": "^2.9.0",
    "nativescript-vue-devtools": "^1.5.1",
    "net": "^1.0.2",
    "os-browserify": "^0.3.0",
    "path-browserify": "^1.0.1",
    "python": "^0.0.4",
    "stream-browserify": "^3.0.0",
    "stream-http": "^3.2.0",
    "tty-browserify": "0.0.1",
    "url": "^0.11.0",
    "util": "^0.12.4",
    "vuedraggable": "^2.24.3",
    "vuex": "^3.6.2"
  },
  "devDependencies": {
    "@babel/core": "^7.4.4",
    "@babel/preset-env": "^7.4.4",
    "@nativescript/android": "8.1.1",
    "@nativescript/ios": "8.3.3",
    "@nativescript/webpack": "~5.0.0-beta.0",
    "@upstatement/eslint-config": "^0.4.2",
    "@upstatement/prettier-config": "^0.3.0",
    "babel-eslint": "^10.0.3",
    "babel-loader": "^8.0.6",
    "eslint": ">6.5.1",
    "eslint-config-prettier": "^6.4.0",
    "eslint-plugin-vue": ">5.2.3",
    "husky": "^3.0.8",
    "lint-staged": "^9.4.2",
    "nativescript": "^8.0.2",
    "nativescript-vue-template-compiler": "^2.9.0",
    "node-sass": "^6.0.1",
    "prettier": "^1.18.2",
    "vue-eslint-parser": "^6.0.4",
    "vue-loader": "15.9.3"
  },
}

After a ns clean and ns install to be safe I'm still seeing the same behavior on iOS when using 2.4.4

triniwiz commented 1 year ago

Do you have any custom delegates and where is the initializeApp called ?

ajveach commented 1 year ago

No, there are no delegates that we have created custom for this app. initializeApp is called in the entry file for the app (main.js).

souriscloud commented 1 year ago

Encountering same issues

souriscloud commented 1 year ago

@ajveach this has been now fixed in 2.5.2, just checked on that

so I believe you can resolve this issue @triniwiz since I experienced same problem before 2.5.2 :)

ajveach commented 1 year ago

Thanks for the heads up, @souriscloud . I just upgraded all of the packages to 2.5.2 in my project, ran ns clean and ns install, but I'm still seeing the same behavior. Did you make any other changes to your project before it started working?

I also just updated nativescript/core to 8.4.1, nativescript CLI to 8.4.0, and nativescript/ios to 8.4.0, but it still never initializes.

meganedesigns commented 1 year ago

I'm seeing the same issue. I've tried using versions 2.4.4 and 2.5.2.

Here are my dependencies:

"dependencies": {
    "@nativescript/apple-sign-in": "^1.0.0",
    "@nativescript/background-http": "^6.0.0",
    "@nativescript/core": "~8.2.0",
    "@nativescript/facebook": "~2.1.0",
    "@nativescript/firebase-analytics": "~2.5",
    "@nativescript/firebase-core": "~2.5",
    "@nativescript/firebase-messaging": "~2.5",
    "@nativescript/google-signin": "^1.0.0",
    "@nativescript/imagepicker": "^1.0.6",
    "@nativescript/local-notifications": "^6.0.0",
    "@nativescript/theme": "~3.0.1",
    "@triniwiz/nativescript-socketio": "^4.0.1",
    "@triniwiz/nativescript-toasty": "^4.1.3",
    "assert": "^2.0.0",
    "axios": "^0.24.0",
    "browserify-zlib": "^0.2.0",
    "buffer": "^6.0.3",
    "facebookgraph": "^0.4.0",
    "highlight-words-core": "^1.2.2",
    "https-browserify": "^1.0.0",
    "nativescript-appversion": "github:imandyie/nativescript-appversion",
    "nativescript-fonticon": "^2.0.2",
    "nativescript-gif": "^5.0.0",
    "nativescript-phone": "^3.0.2",
    "nativescript-ui-listview": "^10.0.2",
    "nativescript-vue": "~2.9.0",
    "nativescript-vue-template-compiler": "~2.9.0",
    "os-browserify": "^0.3.0",
    "path": "^0.12.7",
    "platform": "^1.3.6",
    "rxjs": "^7.5.5",
    "sass": "^1.32.8",
    "stream-browserify": "^3.0.0",
    "stream-http": "^3.2.0",
    "tty-browserify": "0.0.1",
    "url": "^0.11.0",
    "util": "^0.12.4",
    "v-mask": "^2.3.0",
    "vue-axios": "^3.4.0",
    "vuex": "^3.6.2"
  },
  "devDependencies": {
    "@nativescript/android": "8.2.2",
    "@nativescript/ios": "~8.2.0",
    "@nativescript/webpack": "~5.0.0",
    "@vue/devtools": "^5.3.4",
    "nativescript-vue-devtools": "^1.5.1"
  }

Here's my initialization script in main.js. I've tried a few different variations to try to console out successes/errors, but I get nothing.

const defaultApp = await firebase().initializeApp();

It's super bizarre because Firebase was working initially on iOS when we last test in early October, and then it stopped. Android works fine. Sending out notifications via the app is one of the main features, so Firebase not initializing is a big deal for us.

@triniwiz or @souriscloud if you have any ideas, please let me know.

triniwiz commented 1 year ago

Possible to share the entire main.js ?

meganedesigns commented 1 year ago

Possible to share the entire main.js ? @triniwiz


// import VueDevtools from 'nativescript-vue-devtools';
import Vue from 'vue';
import store from "./store";
import Loading from "./pages/Loading";
import RadListView from 'nativescript-ui-listview/vue';
import router from "./router";
import notificationsLocal from "./notifications";
import { TNSFontIcon, fonticon } from 'nativescript-fonticon';
import { Gif } from "nativescript-gif";
import '@nativescript/local-notifications';
import { firebase } from '@nativescript/firebase-core';
import '@nativescript/firebase-analytics';
import Theme from "@nativescript/theme";
import { GoogleSignin } from '@nativescript/google-signin';
import { LoginManager } from '@nativescript/facebook';
import { init } from '@nativescript/background-http';
init();

const defaultApp = async function () { console.log('defaultApp function started'); await firebase().initializeApp(); console.log('Firebase Initialized'); } defaultApp();

LoginManager.init(); GoogleSignin.configure();

Vue.prototype.$goTo = function (to, props, params) { if (!router[to]) return;

try {
    firebase().analytics().logEvent('select_content', {
        'content_type': 'page',
        'item_id': to
    });
} catch (e) {}

this.$navigateTo(router[to], {
    props,
    ...params // clearHistory, backstackVisible
});

};

Vue.prototype.$goBack = function () {

firebase().analytics().logEvent('select_content', {
    'content_type': 'page',
    'item_id': '$navigateBack'
});

this.$navigateBack();

}; Vue.registerElement("Gif", () => Gif); Vue.use(RadListView);

// Load TNSFonticon TNSFontIcon.debug = false; TNSFontIcon.paths = { fa: './assets/css/fontawesome.min.css', fal: './assets/css/light.min.css', far: './assets/css/regular.min.css', fas: './assets/css/solid.min.css', fab: './assets/css/brand.min.css' }; TNSFontIcon.loadCss(); Vue.filter('fonticon', fonticon);

Vue.config.silent = false; Vue.config.suppressRenderLogs = true;

new Vue({ store, mounted() { Theme.setMode(Theme.Light); }, render: h => h("frame", [h(Loading)]) }).$start();

I forgot I had `firebase().initializeApp()` wrapped in an async function to prevent issues with webpack.

I get the following message after`firebase().initializeApp()` runs:

Later in the app when trying to use firebase that hasn't been instantiated, I get this message:

9.6.0 - [FirebaseCore][I-COR000003] The default Firebase app has not yet been configured. Add `FirebaseApp.configure()` to your application initialization. This can be done in in the App Delegate's application(_:didFinishLaunchingWithOptions:)` (or the `@main` struct's initializer in SwiftUI). Read more: https://goo.gl/ctyzm8.
souriscloud commented 1 year ago

@meganedesigns sorry but after 3-4yrs on {N}-Vue, i've tooked few no-sleep weeks to completely recreate pretty complex and big application to other framework, since the issues I've faced for last year was constantly reocurring and made us unable to even deploy any update :(. I do not blame {N}! There could be some mis-usage, given by size of the app, also it was my first mobile project so I was learning on the way how to even follow the mobile rules, and some of bad practices was still deep in the app probably. I am not really sure because I've tried everything, believe me I've literally sleeped in the source to find a way out.. but since i do not know native sides so well, it was not leading anywhere...

Wish you luck to get all working well. Also if you are not on {N} discord, make sure you join it, you could get more direct help there, its pretty good place to use the search fci first, many things are already there.

kefahB commented 1 year ago

@souriscloud sorry to hear that, But I have 2 app in production one of them are payment app and it work fine, yes NS some documentation problem but currently they are on it.

The problem is most of the plugin are not well documented and the demo project are not updated, this is a huge problem but it is also our responsibility to help, it is open source and every body should help as he can :)

kefahB commented 1 year ago

@meganedesigns please post the code of your app.ts also

triniwiz commented 1 year ago

Hey @meganedesigns sorry for the late reply, the store seems to be the next place to check since it's possible it may be doing something before the app launches

triniwiz commented 1 year ago

@souriscloud sorry to hear but helps us to help you :)

shirakaba commented 1 year ago

@meganedesigns It may not be the problem at hand, but I notice that you have a race condition. You call defaultApp(), which is a Promise, but you didn't write it as await defaultApp() (or if top-level await is not supported, a classic Promise chain with .then()), so there's a chance that the app will mount and use Firebase functionality before having initialised:

const defaultApp = async function () {
    console.log('defaultApp function started');
    await firebase().initializeApp();
    console.log('Firebase Initialized');
}
- defaultApp();
+ await defaultApp();
+
+ // Or, if top-level await is not supported:
+ // defaultApp().then(() => {
+ // // All the lines that you originally had below defaultApp();
+ // })
shirakaba commented 1 year ago

@meganedesigns This is worrying:

- [GoogleUtilities/AppDelegateSwizzler][I-SWZ001014] App Delegate does not conform to UIApplicationDelegate protocol.

Google Firebase swizzles the methods of AppDelegate to magically set itself up. But it seems to think your AppDelegate doesn't conform to UIApplicationDelegate, so it's unable to proceed.

I'm aware that @nativescript/ios provides the AppDelegate for you. Did you use a custom one (e.g. created via JS) or anything? Or @triniwiz, does anything come to mind?

triniwiz commented 1 year ago

@shirakaba Interesting find, another thing u can do after applying Jamie's suggestion is try moving the firebase init after facebook and google sdk init calls

meganedesigns commented 1 year ago

Thanks for all the suggestions @shirakaba and @triniwiz

I've tried initializing the app after defaultApp() is run (ie after firebase initializes). However Firebase still never initializes, so the app never initializes (ie it crashes).

const defaultApp = async function () {
    console.log('defaultApp function started');
    await firebase().initializeApp();
    console.log('Firebase Initialized');
}
defaultApp().then(() => {
    init();

    LoginManager.init();
    GoogleSignin.configure();
    new Vue({
        store,
        mounted() {
            Theme.setMode(Theme.Light);
        },
        render: h => h("frame", [h(Loading)])
    }).$start();
});

I've tried keeping the background-http, Facebook, and Google inits before and after running defaultApp(), and there's no difference. I've also tried removing store.js and Firebase does not initialize.

If I downgrade my Firebase packages to version 2.0.1, Firebase will initialize on iOS, but then there are issues with Facebook login.

I plan to do a clean build later today with just the firebase packages to see if I can get it to initialize. If it does, I'll slowly add other packages back in to see what's conflicting.

shirakaba commented 1 year ago

Can you show us your AppDelegate? I’m curious whether it’s not confirming to the UIApplicationDelegate protocol somehow.

j99ht commented 10 months ago

I'm having the same issue with

    "@nativescript/firebase-core": "^3.2.0",
    "@nativescript/firebase-messaging": "^3.2.0",

Is there any workaround I can implement?

This is my main.ts

import { platformNativeScript, runNativeScriptAngularApp } from '@nativescript/angular';
import { AppModule } from './app/app.module';
import { firebase } from '@nativescript/firebase-core';
import '@nativescript/firebase-messaging';

// await firebase().initializeApp();
const defaultApp = async function () {
    console.log('defaultApp function started');
    const firebaseApp = await firebase().initializeApp();
    console.log('Firebase Initialized');
}

await defaultApp();

runNativeScriptAngularApp({
    appModuleBootstrap: () => platformNativeScript().bootstrapModule(AppModule),
});

I'm running NS 8.3.3 and @nativescript/ios 8.3.3

chris-praxis commented 8 months ago

I'm running into this with plug-in v3.2.0

unipro-ArnaudKalicharam commented 2 months ago

@triniwiz That still seems to be an issue on latest @nativescript/firebase-core i.e. as at today's date: v3.3.1 - Also tried to revert to older versions of firebase as suggested in the thread (and ended up trying every ~ versions from 1.0.x till latest) but that still seems to be happening. The main issue is that it silently fails and crashes the iOS app without any helpful debug information, and thus leaving me with no idea as to how to fix. As a note, we recently upgraded from the deprecated @nativescript/firebase v11.1.3 - unsure if it's the massive jump that is causing this to happen. I'd think that there might be older code hooking into initializeApp, but finding no way to identify. Any help or thoughts would be very much appreciated πŸ™ Thanks πŸ™‚

unipro-ArnaudKalicharam commented 2 months ago

Okay - I've got an update for this for whoever gets stuck on that in the future: apparently iOS has issues with async/await. Changing it to use the promise right on initializeApp() now revives the iOS app build.

i.e. something like this:

- await firebase().initializeApp();
+ firebase().initializeApp().then(() => {
+   console.log("firebase initialized");
+ });