Open faiyaz26 opened 6 years ago
Please keep in mind that, even though this solution works, this is undocumented behavior, and it can stop working in any update.
This is how I fixed this on my project
import * as firebase from "nativescript-plugin-firebase";
// change requestPhoneAuthVerificationCode, which is the internal method that opens the prompt. this only needs to be done once
firebase["requestPhoneAuthVerificationCode"] = onRequestPhoneAuthVerificationCode;
// call firebase login
const loginPromise = firebase.login({
type: firebase.LoginType.PHONE,
phoneOptions: { phoneNumber, verificationPrompt: promptMessage }
})
// this will be called when the plugin asks for the sms code
function onRequestPhoneAuthVerificationCode(
onUserResponse: (phoneAuthVerificationCode: string) => void,
verificationPrompt: string) {
// ... this is where you can write your code to open your prompt, or do whatever you like
// this is the original code, which can be found here: https://github.com/EddyVerbruggen/nativescript-plugin-firebase/blob/master/src/firebase-common.ts#L131
prompt(verificationPrompt || "Verification code").then(promptResult => {
if (!promptResult.result) {
return;
}
onUserResponse(promptResult.text);
});
}
Also consider that the plugin behavior is different between Android and iOS:
onRequestPhoneAuthVerificationCode
is called immediately. and if onUserResponse
callback is not called the loginPromise
will never be resolved
See source for iOS: https://github.com/EddyVerbruggen/nativescript-plugin-firebase/blob/master/src/firebase.ios.ts#L1289onRequestPhoneAuthVerificationCode
might never be called (if the authentication happens automatically behind the scenes), and if it is, it will be called 3 seconds after the call to firebase.login
.
See source for Android: https://github.com/EddyVerbruggen/nativescript-plugin-firebase/blob/master/src/firebase.android.ts#L1134In my opinion, this should and can easily be supported by the plugin. Maybe @EddyVerbruggen could weigh in on how this could be added to the plugin so that someone can open a PR.
@tmldsousa thanks man, you're awesome. I was looking for a way to override the popup since there is not even a way to change the title text and buttons text! And for a non-english application that's not good to see. Hope this gets implemented in a better way.
@EddyVerbruggen bump on this. I would like to open a PR on this so that I can do something other than an prompt to enter a code—I'd like to build out my own page that's a better UI for this sort of thing. Thoughts?
@EddyVerbruggen it appears once you remove prompt from phone verification login the entire process stops. How can one present their own UI. Similar to Whatapp verification process?
Eventual resolved custom log in by return a promise in firebase["requestPhoneAuthVerificationCode"], once firebase returns user, returned promise's resolve method is called to complete verification/login flow.
Code snippets below
// reference to nativescript-plugin-firebase onUserResponse function needed to complete authentication verification code capturing
private _funcUserResponse: (results: string) => {};
//global variables that reference promise resolve and reject to be used later on
verificationPromiseResolver = null;
verificationPromiseRejector = null;
verificationPromise = new Promise((resolve, reject) => {
this.verificationPromiseResolver = resolve;
this.verificationPromiseRejector = reject;
});
firebase["requestPhoneAuthVerificationCode"] = (onUserResponse, verificationPrompt) => {
this._funcUserResponse = onUserResponse;
return this.verificationPromise;
}
@tmldsousa great find! I managed to do this to my own custom screen and used observables to emit events
Here's how I did this in a way that it works well on Android but having haven't tested it on iOS which gives me a Custom URL Scheme error which I apparently have to add to Info.plist
Tried adding the given custom URL to Info.plist but still no luck, and I think the way I added it to Info.plist is not right.
EDIT: Finally made it work in iOS with these lines added to my Info.plist
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>com.googleusercontent.apps.{{CLIENT_ID}}</string>
</array>
</dict>
</array>
import { Observable } from "tns-core-modules/data/observable";
export class VerificationObservableModel extends Observable { private _verificationCode: number; private _verificationResponse: any; private _verificationError: any;
get verificationCode(): number {
return this._verificationCode;
}
set verificationCode(value: number) {
this._verificationCode = value;
}
get verificationResponse(): any {
return this._verificationResponse;
}
set verificationResponse(value: any) {
this._verificationResponse = value;
}
get verificationError(): any {
return this._verificationError;
}
set verificationError(value: any) {
this._verificationError = value;
}
}
- **login.component.ts**
```TS
import { FirebaseService } from "~/app/services/firebase/firebase.service";
import * as firebase from 'nativescript-plugin-firebase';
firebase["requestPhoneAuthVerificationCode"] = onRequestPhoneAuthVerificationCode;
import { VerificationObservableModel } from "~/app/models/verification-custom-observable";
var verificationObservable: VerificationObservableModel = new VerificationObservableModel();
function onRequestPhoneAuthVerificationCode(onUserResponse: (phoneAuthVerificationCode: string) => void, verificationPrompt: string) {
verificationObservable.on("onverify", (data) => {
onUserResponse(data.object.get("verificationCode"));
});
}
@Component({
selector: "ns-login",
moduleId: module.id,
templateUrl: "./login.component.html",
styleUrls: ["./login.component.scss"]
})
export class LoginComponent {
onCodeVerificationSend() {
this.isProcessing = true;
firebase.logout();
this._firebase.onSendSMSVerification(this.phoneNumber);
setTimeout(() => {
this.isProcessing = false;
this.isCodeSent = true;
}, 3000);
}
onCodeVerify() {
this.isProcessing = true;
verificationObservable.set("verificationCode", this.verificationCode);
let eventData: EventData = {
eventName: "onverify",
object: verificationObservable
};
verificationObservable.notify(eventData);
this._firebase.verificationObservable.on("onverificationsuccess", (data) => {
console.dir(data.object.get("verificationResponse"));
this.isProcessing = false;
this.reset();
this._navigationService.navigateToHomeScreen(true);
});
this._firebase.verificationObservable.on("onverificationerror", (data) => {
this.isProcessing = false;
console.dir(data.object.get("verificationError"));
alert("Verification Error");
this.onBack();
});
}
}
import { Injectable } from '@angular/core';
import * as firebase from 'nativescript-plugin-firebase';
import { EventData } from 'tns-core-modules/ui/page/page';
import { VerificationObservableModel } from '~/app/models/verification-custom-observable';
@Injectable() export class FirebaseService { verificationObservable: VerificationObservableModel = new VerificationObservableModel();
constructor() {
firebase.init({
persist: true,
}).then(() => {
console.log("Firebase Initiliazed");
}).catch((err) => {
console.log(err);
});
}
onSendSMSVerification(phoneNumber: string, promptMessage: string = '') {
firebase.login({
type: firebase.LoginType.PHONE,
phoneOptions: { phoneNumber, verificationPrompt: promptMessage }
}).then((response) => {
this.verificationObservable.set("verificationResponse", response);
let eventData: EventData = {
eventName: "onverificationsuccess",
object: this.verificationObservable
}
this.verificationObservable.notify(eventData);
}).catch((err) => {
this.verificationObservable.set("verificationError", err);
let eventData: EventData = {
eventName: "onverificationerror",
object: this.verificationObservable
}
this.verificationObservable.notify(eventData);
});
}
}
Hi I don't know how to do it with vue
I am trying to use phone number based authentication. It seems this library auto-generates a prompt for the verification code input. Is it possible to handle this prompt from the application side ( like I want to show a form )?
Another thing, when the prompt is being shown, if I hit the cancel button, my application gets stuck, what type of exception handling should I use for that?