Nativescript-plugin-firebase: new iOS error on google auth - presenting view controller must be set

Created on 21 Aug 2019  路  16Comments  路  Source: EddyVerbruggen/nativescript-plugin-firebase

Google Auth was previously working on iOS but now I am receiving this error with no changes to codebase: "presenting view controller must be set"

Most helpful comment

Google Auth was previously working on iOS but now I am receiving this error with no changes to codebase: "presenting view controller must be set"

@edmundpf instead of this GIDSignIn.sharedInstance()?.uidelegate = self
try this GIDSignIn.sharedInstance()?.presentingViewController = self

All 16 comments

Please share your repo.

Please share your repo.

I'm using this for a private project that I'm not allowed to share but I will include anything relevant to the plugin, please let me know if I'm missing anything. Thank you for the help!

  • google-services.json in app/App_Resources/Android/
  • GoogleService-Info.plist in app/App_Resources/iOS/
  • firebase.nativescript.json
{
    "external_push_client_only": false,
    "using_ios": true,
    "using_android": true,
    "firestore": true,
    "realtimedb": false,
    "authentication": true,
    "remote_config": false,
    "performance_monitoring": false,
    "messaging": false,
    "in_app_messaging": false,
    "crashlytics": false,
    "crash_reporting": false,
    "storage": false,
    "functions": false,
    "facebook_auth": true,
    "google_auth": true,
    "admob": false,
    "invites": false,
    "dynamic_links": false,
    "ml_kit": false
}
  • package.json dependencies (nativescript-plugin-firebase v8.3.2)
  "dependencies": {
    "lodash": "^4.17.11",
    "nativescript-bluetooth": "^2.0.0-beta.23",
    "nativescript-iqkeyboardmanager": "^1.5.1",
    "nativescript-plugin-firebase": "^8.3.2",
    "nativescript-toasty": "^1.3.0",
    "nativescript-vue": "^2.0.0",
    "nativescript-vuex-persistent": "^1.2.0",
    "tns-core-modules": "^5.0.2",
    "vuex": "^3.0.1"
  },
  • Google login method
    async loginGoogle() {
        return await firebase
        .login({
            type: firebase.LoginType.GOOGLE
        })
    },
  • Google login call where error originates (called on button click)
const res = await userFunctions.loginGoogle()

The relevant bit is the page structure (because it seems like the code can't resolve the page controller) so I really need an app I can run to reproduce it. Of course I don't want your actual project, just a very simple app that shows the issue.

The relevant bit is the page structure (because it seems like the code can't resolve the page controller) so I really need an app I can run to reproduce it. Of course I don't want your actual project, just a very simple app that shows the issue.

Gotcha, thanks again for the help!

  • Auth Page
<template>
    <Page class="page" actionBarHidden="true">
        <FlexboxLayout flexDirection="column">
            <mainLogo/>
            <StackLayout class="form">
                <TextField
                    hint="Email..."
                    v-model="emailText"
                    class="input input-rounded input-font m-t-10"
                    v-bind:class="{ danger: emailDanger, success: emailSuccess }"
                />
                <TextField
                    hint="Password..."
                    v-model="passText"
                    class="input input-rounded input-font m-t-25 m-b-25"
                    secure="true"
                    v-bind:class="{ danger: passDanger, success: passSuccess }"
                />
                <Button
                    class="btn btn-primary btn-ruby btn-rounded-sm"
                    text="Login"
                    :isEnabled="loginEnabled"
                    @tap="loginEvent"
                />
                <Button
                    class="btn btn-primary btn-purple btn-rounded-sm m-y-25"
                    text="Signup"
                    @tap="signupPageNav"
                />
                <Label
                    class="text-center m-x-5 m-t-10 t-18"
                    v-bind:class="{ 'text-danger': feedbackDanger }"
                    :text="feedbackText"
                    textWrap="true"
                />
                <StackLayout orientation="horizontal">
                    <Button
                        class="btn btn-primary btn-error btn-circle-half btn-left fab"
                        :text="googleIcon"
                        width="25%"
                        @tap="googleLogin"
                    />
                    <Button
                        class="btn btn-primary btn-blue btn-circle-half btn-right fab"
                        :text="facebookIcon"
                        width="25%"
                        @tap="facebookLogin"
                    />
                </StackLayout>
            </StackLayout>
        </FlexboxLayout>
    </Page>
</template>

<script>

import userMixin from '~/mixins/userMixin'
import iconMixin from '~/mixins/iconMixin'
import fireStore from '~/mixins/fireStore'
import mainLogo from '~/components/mainLogo'
import signupPage from '~/pages/signupPage'
import { userFunctions } from '~/utils/fire'
import {
    slideNav,
    noTransNav,
    syncDevices
} from '~/utils/miscFunctions'

export default {
    mixins: [
        userMixin,
        iconMixin,
        fireStore,
    ],
    data() {
        return {
            loginEnabled: true,
        }
    },
    components: {
        mainLogo,
    },
    methods: {
        signupPageNav() {
            slideNav(this,
                    signupPage,
                    { email: this.emailText,
                        password: this.passText,
                        signin_method: 'email' })
        },
        async loginEvent() {
            try {
                const res = await userFunctions.login({
                    email: this.emailText,
                    password: this.passText,
                })
                var getRes
                try {
                    getRes = await this.getData(res.uid)
                }
                catch (error) {
                    this.$logError(error)
                    getRes = {}
                }
                syncDevices.bind(this)(getRes)
                if (getRes.update_timestamp >= this.$store.state.update_timestamp) {
                    this.$store.dispatch('setData', {
                        ...getRes,
                        uid: res.uid,
                        logged_in: true,
                        signin_method: 'email',
                        devices: this.$store.state.devices,
                        cur_device: this.$store.state.cur_device,
                    })
                }
                else {
                    this.$store.dispatch('setData', {
                        uid: res.uid,
                        logged_in: true,
                        signin_method: 'email',
                        devices: this.$store.state.devices,
                        cur_device: this.$store.state.cur_device,
                    })
                }
                this.feedbackText = ''
                this.feedbackDanger = false
            }
            catch (error) {
                this.$logError(error)
                this.feedbackDanger = true
                this.feedbackText = 'Could not login. Please try again.'
            }
        },
        async googleLogin() {
            try {
                const res = await userFunctions.loginGoogle()
                var getRes
                try {
                    getRes = await this.getData(res.uid)
                }
                catch (error) {
                    this.$logError(error)
                    getRes = {}
                }
                syncDevices.bind(this)(getRes)
                if (getRes.logged_in != null) {
                    if (getRes.update_timestamp >= this.$store.state.update_timestamp) {
                        this.$store.dispatch('setData', {
                            ...getRes,
                            uid: res.uid,
                            logged_in: true,
                            signin_method: 'google',
                            devices: this.$store.state.devices,
                            cur_device: this.$store.state.cur_device,
                        })
                    }
                    else {
                        this.$store.dispatch('setData', {
                            uid: res.uid,
                            logged_in: true,
                            signin_method: 'google',
                            devices: this.$store.state.devices,
                            cur_device: this.$store.state.cur_device,
                        })
                    }
                    this.feedbackText = ''
                    this.feedbackDanger = false
                }
                else {
                    this.$store.dispatch('setState', {
                        uid: res.uid
                    })
                    slideNav(this,
                            signupPage,
                            {
                                email: res.email,
                                signin_method: 'google',
                            })
                }
            }
            catch (error) {
                this.$logError(error)
            }
        },
        async facebookLogin() {
            try {
                const res = await userFunctions.loginFacebook()
                var getRes
                try {
                    getRes = await this.getData(res.uid)
                }
                catch (error) {
                    this.$logError(error)
                    getRes = {}
                }
                syncDevices.bind(this)(getRes)
                if (getRes.logged_in != null) {
                    if (getRes.update_timestamp >= this.$store.state.update_timestamp) {
                        this.$store.dispatch('setData', {
                            ...getRes,
                            uid: res.uid,
                            logged_in: true,
                            devices: deviceInfo.devices,
                            devices: this.$store.state.devices,
                            cur_device: this.$store.state.cur_device,
                        })
                    }
                    else {
                        this.$store.dispatch('setData', {
                            uid: res.uid,
                            logged_in: true,
                            devices: deviceInfo.devices,
                            devices: this.$store.state.devices,
                            cur_device: this.$store.state.cur_device,
                        })
                    }
                    this.feedbackText = ''
                    this.feedbackDanger = false
                }
                else {
                    this.$store.dispatch('setState', {
                        uid: res.uid
                    })
                    slideNav(this,
                            signupPage,
                            {
                                email: res.email,
                                signin_method: 'facebook',
                            })
                }
            }
            catch (error) {
                this.$logError(error)
            }
        },
    }
}

</script>
  • App.vue
<template>
    <mainPage v-if="$store.state.logged_in"/>
    <authPage v-else/>
</template>

<script >

import mainPage from './pages/mainPage'
import authPage from './pages/authPage'

export default {
    data: function() {
        return {

        }
    },
    components: {
        mainPage,
        authPage,
    },
}

</script>

I could be barking up the wrong tree but GoogleSignIn just updated their pod file recently from 4.4.0 to 5.0.0... on the 14th this month. One of the things that was changed was replacing uiDelegate with presentingViewController (https://developers.google.com/identity/sign-in/ios/release).

I could be barking up the wrong tree but GoogleSignIn just updated their pod file recently from 4.4.0 to 5.0.0... on the 14th this month. One of the things that was changed was replacing uiDelegate with presentingViewController (https://developers.google.com/identity/sign-in/ios/release).

That would make sense. I was actually on v9.0.2 of the plugin and see 6 days ago v9.1.0 was added to accommodate the new SDK's. I'll let you guys know if that resolves the issue.

@EddyVerbruggen @brownkevg after further testing all login/signup functionality only on iOS was recently broken for me at least on 9.0.2 but the update to 9.1.0 fixed all of it, I'll go ahead and close this

Google Auth was previously working on iOS but now I am receiving this error with no changes to codebase: "presenting view controller must be set"

@edmundpf instead of this GIDSignIn.sharedInstance()?.uidelegate = self
try this GIDSignIn.sharedInstance()?.presentingViewController = self

Google Auth was previously working on iOS but now I am receiving this error with no changes to codebase: "presenting view controller must be set"

@edmundpf instead of this GIDSignIn.sharedInstance()?.uidelegate = self
try this GIDSignIn.sharedInstance()?.presentingViewController = self

actually you should use both, in order to perform this action

Yes use both GIDSignIn.sharedInstance()?.uidelegate = self and GIDSignIn.sharedInstance()?.presentingViewController = self
in order to resolve this issue.

I got the same issue and resolved it by using both of the above statements.

@Vikrant-art is there some code I need to integrate into the plugin? Can you perhaps do a PR even? Cheers!

@Vikrant-art Where in this NativeScript project would I integrate that code? I mean, that looks like Swift to me, and that's not what this repo uses. Are you sure you're looking at the right repo?

Google Auth was previously working on iOS but now I am receiving this error with no changes to codebase: "presenting view controller must be set"

@edmundpf instead of this GIDSignIn.sharedInstance()?.uidelegate = self
try this GIDSignIn.sharedInstance()?.presentingViewController = self

actually you should use both, in order to perform this action

Thank you so much. Its worked

That's work for me... Hurrayyyyyy

@rajni1721 Can you please share what you鈥檝e changed exactly, because I鈥檓 not entirely clear if there鈥檚 something I can change in the plugin.

Google Auth was previously working on iOS but now I am receiving this error with no changes to codebase: "presenting view controller must be set"

@edmundpf instead of this GIDSignIn.sharedInstance()?.uidelegate = self
try this GIDSignIn.sharedInstance()?.presentingViewController = self

actually you should use both, in order to perform this action

thanks. its worked

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tactusoft picture tactusoft  路  3Comments

tsili852 picture tsili852  路  3Comments

bunower picture bunower  路  3Comments

jlooper picture jlooper  路  3Comments

SBD580 picture SBD580  路  3Comments