Leandro Furini
Leandro Furini

Reputation: 69

Firebase onCall function return Error with 4G network but works with Wifi

On my PWA, there is some functions running by onCall functions. It was working properly, but some days ago any of these functions is returning "Firebase error: internal" only when the PWA is running on a mobile with 4g network. In a Wifi network everything is working as expected.

Some extra informations:

  1. When in 4g, the function return the error, but without any message log on firebase console. Even "Function execution started" or "Function execution took..." is displayed.
  2. Yes my 4g is ok. Despite this onCall functions error, others parts that demands connection is working fine (for example: any database call from SDK firebase)
  3. It's not a specific problem with my device. In some devices it works, in others no... I tested with differents devices with IOS or Android.

My code - Web:

async checkFirstLogin(uid) {
    this.apiPortal = this.functions.httpsCallable('apiPortal')
    let body = {
      action: 'checkFirstLogin',       
      uid: uid
    }
    return this.apiPortal({body: body})
    .then((response) => {
      return response.data.success
    }).catch((e) => {
      console.log('========> Error', e) //returns "Firebase error: internal"
    })
}

My Code - function

const admin = require('firebase-admin');
const functions = require('firebase-functions');

try {
    admin.initializeApp();
} catch (e) {}

const runtimeOpts = {
    timeoutSeconds: 60,
    memory: '2GB'
}

exports.default = functions.region('southamerica-east1').runWith(runtimeOpts).https.onCall((data, context) => {
    if (!context.auth) {
        return {
            status: 'error', 
            code: 401, 
            message: 'Not signed in'
        }
    }
    functions.logger.log(`#apiPortal - starting - action:${data.body.action}`)
    if (data.body.action==='checkFirstLogin') {
        let ref = admin.database().ref(`login/${data.body.uid}`)
        return ref.once('value').then((data) => { 
          if (data.val()) {
            let usr = data.val()
            return {success: true, data: usr.hasOwnProperty('last_login')} 
          } else {
            return {success: true, data: null}
          }
        }).catch((e) => {
          throw new functions.https.HttpsError('Unknown error', e.message, e)
        })
    } else {
        return {success: false, data: null}
    }
  }
})

Upvotes: 1

Views: 196

Answers (2)

Guilherme Cercal
Guilherme Cercal

Reputation: 106

i'm facing this exact same issue and the only workaround i found for this is use firebase hosting to create rewritable paths to your function. This is a solution since firebase hosting is not being affected by this extremely annoying behavior of TIM 4g network (in my case and the case for @leandro-furini).

how to:

  1. publish a website using firebase hosting (if you already have one, you can use it, otherwise you can just publish a dummy website).

  2. in your firebase.json file in the website project, you need to place rewrite instructions to your functions just like these:

{
   ...

   "rewrites": [
     {
        "source": "myFunctionPath", // the name you want to give to the path
        "function": "nameOfMyFunction" // the name of your function in the firebase
     },
   ]
}

and deploy your website with firebase cli: firebase deploy --only hosting

  1. Change your firebase sdk (in my case i'm using AngularFire) to use a different origin, in the case, the origin must be the firebase hosting website address eg.: https://my-app.web.app (this is also works with custom domains added on firebase hosting).
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule.withServerTransition({ appId: 'serverApp' }),
    AppRoutingModule,
    LayoutModule,
    SwiperModule,
    AngularFireModule.initializeApp(environment.firebase),
    NgcCookieConsentModule.forRoot(cookieConfig),
    SweetAlert2Module.forRoot(),
    NgxMaskModule.forRoot()
  ],
  providers: [
    ScreenTrackingService, UserTrackingService, AngularFireAuthGuard,
    //{ provide: REGION, useValue: 'southamerica-east1' },
    //{ provide: USE_FUNCTIONS_EMULATOR, useValue: ['localhost', 5001] },
    { provide: LOCALE_ID, useValue: 'pt' },
    { provide: ORIGIN, useValue: 'https://my-app.web.app' } // ** HERE GOES YOUR HOSTIN ADDRESS **
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

this snippet is from Angular with AngularFire, but im 100% sure that is possible to configure the origin of your callable functions using the native firebase sdk.

  1. Make sure your cloud functions are published on us-central1 region (only works in this region).

that's it!! now when you call a callable function from your pwa the address will be:

https://my-app.web.app/myFunctionPath

and will reach the same result as calling

https://us-central1-my-project.cloudfunctions.net/nameOfMyFunction

Upvotes: 1

Leandro Furini
Leandro Furini

Reputation: 69

We found that the problem is specifically with TIM 4g network. It s a DNS problem of them that do not resolve the url of our API in GCP. Today, after 3 days of problems, it's working again

Upvotes: 1

Related Questions