nativescript-firebase-updated-new
Version:
984 lines (983 loc) • 114 kB
JavaScript
import { Application, Utils, AndroidApplication } from "@nativescript/core";
import lazy from "@nativescript/core/utils/lazy";
import { DocumentSnapshot as DocumentSnapshotBase, FieldValue, firebase, GeoPoint, isDocumentReference } from "./firebase-common";
import * as firebaseFunctions from "./functions/functions";
import * as firebaseMessaging from "./messaging/messaging";
export var QueryOrderByType;
(function (QueryOrderByType) {
QueryOrderByType[QueryOrderByType["KEY"] = 0] = "KEY";
QueryOrderByType[QueryOrderByType["VALUE"] = 1] = "VALUE";
QueryOrderByType[QueryOrderByType["CHILD"] = 2] = "CHILD";
QueryOrderByType[QueryOrderByType["PRIORITY"] = 3] = "PRIORITY";
})(QueryOrderByType || (QueryOrderByType = {}));
export var QueryRangeType;
(function (QueryRangeType) {
QueryRangeType[QueryRangeType["START_AT"] = 0] = "START_AT";
QueryRangeType[QueryRangeType["END_AT"] = 1] = "END_AT";
QueryRangeType[QueryRangeType["EQUAL_TO"] = 2] = "EQUAL_TO";
})(QueryRangeType || (QueryRangeType = {}));
export var QueryLimitType;
(function (QueryLimitType) {
QueryLimitType[QueryLimitType["FIRST"] = 0] = "FIRST";
QueryLimitType[QueryLimitType["LAST"] = 1] = "LAST";
})(QueryLimitType || (QueryLimitType = {}));
const gmsAds = com.google.android.gms.ads;
const gmsTasks = com.google.android.gms.tasks;
class DocumentSnapshot extends DocumentSnapshotBase {
constructor(snapshot) {
super(snapshot ? snapshot.getId() : null, snapshot.exists(), firebase.toJsObject(snapshot.getData()), firebase.firestore._getDocumentReference(snapshot.getReference()));
this.snapshot = snapshot;
this.metadata = {
fromCache: this.snapshot.getMetadata().isFromCache(),
hasPendingWrites: this.snapshot.getMetadata().hasPendingWrites()
};
this.android = snapshot;
}
}
firebase._launchNotification = null;
firebase._cachedDynamicLink = null;
firebase._googleSignInIdToken = null;
firebase._googleSignInServerAuthCode = null;
firebase._facebookAccessToken = null;
firebase._appleSignInIdToken = null;
let fbCallbackManager = null;
let initializeArguments;
const GOOGLE_SIGNIN_INTENT_ID = 123;
const authEnabled = lazy(() => typeof (com.google.firebase.auth) !== "undefined" && typeof (com.google.firebase.auth.FirebaseAuth) !== "undefined");
const messagingEnabled = lazy(() => !global.FIREBASE_PLUGIN_MESSAGING_DISABLED && typeof (com.google.firebase.messaging) !== "undefined");
const dynamicLinksEnabled = lazy(() => typeof (com.google.firebase.dynamiclinks) !== "undefined");
const dynamicLinkHandler = args => {
if (dynamicLinksEnabled()) {
const emailLink = "" + args.android.getData();
if (authEnabled() && com.google.firebase.auth.FirebaseAuth.getInstance().isSignInWithEmailLink(emailLink)) {
const rememberedEmail = firebase.getRememberedEmailForEmailLinkLogin();
if (rememberedEmail !== undefined) {
const emailLinkOnCompleteListener = new gmsTasks.OnCompleteListener({
onComplete: task => {
if (task.isSuccessful()) {
const authResult = task.getResult();
firebase.notifyAuthStateListeners({
loggedIn: true,
user: toLoginResult(authResult.getUser(), authResult.getAdditionalUserInfo())
});
}
else {
if (firebase._emailLinkErrorCallback) {
firebase._emailLinkErrorCallback("Logging in the user failed. " +
(task.getException() && task.getException().getReason
? task.getException().getReason()
: task.getException()));
}
}
}
});
const user = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser();
if (user) {
const authCredential = com.google.firebase.auth.EmailAuthProvider.getCredentialWithLink(rememberedEmail, emailLink);
user.linkWithCredential(authCredential).addOnCompleteListener(emailLinkOnCompleteListener);
}
else {
com.google.firebase.auth.FirebaseAuth.getInstance().signInWithEmailLink(rememberedEmail, emailLink).addOnCompleteListener(emailLinkOnCompleteListener);
}
}
}
else {
const getDynamicLinksCallback = new gmsTasks.OnSuccessListener({
onSuccess: pendingDynamicLinkData => {
if (pendingDynamicLinkData != null) {
const deepLink = pendingDynamicLinkData.getLink().toString();
const minimumAppVersion = pendingDynamicLinkData.getMinimumAppVersion();
if (firebase._dynamicLinkCallback === null) {
firebase._cachedDynamicLink = {
url: deepLink,
minimumAppVersion: minimumAppVersion
};
}
else {
setTimeout(function () {
firebase._dynamicLinkCallback({
url: deepLink,
minimumAppVersion: minimumAppVersion
});
});
}
}
}
});
const firebaseDynamicLinks = com.google.firebase.dynamiclinks.FirebaseDynamicLinks.getInstance();
firebaseDynamicLinks.getDynamicLink(args.android).addOnSuccessListener(getDynamicLinksCallback);
}
}
};
(() => {
Application.on(Application.launchEvent, args => {
if (messagingEnabled()) {
firebaseMessaging.onAppModuleLaunchEvent(args);
}
});
Application.android.on(AndroidApplication.activityNewIntentEvent, (args) => {
setTimeout(() => {
dynamicLinkHandler({ android: args.intent });
}, 1000);
});
Application.on(Application.resumeEvent, args => {
if (messagingEnabled()) {
firebaseMessaging.onAppModuleResumeEvent(args);
}
});
})();
firebase.toHashMap = obj => {
const node = new java.util.HashMap();
for (const property in obj) {
if (obj.hasOwnProperty(property)) {
if (obj[property] === null) {
node.put(property, null);
}
else {
if (obj[property] === "SERVER_TIMESTAMP") {
node.put(property, com.google.firebase.firestore.FieldValue.serverTimestamp());
}
else if (obj[property] === "DELETE_FIELD") {
node.put(property, com.google.firebase.firestore.FieldValue.delete());
}
else if (obj[property] instanceof FieldValue) {
const fieldValue = obj[property];
if (fieldValue.type === "ARRAY_UNION") {
let values = Array.isArray(fieldValue.value[0]) ? fieldValue.value[0] : fieldValue.value;
values = values.map(v => typeof (v) === "object" ? firebase.toHashMap(v) : v);
node.put(property, com.google.firebase.firestore.FieldValue.arrayUnion(values));
}
else if (fieldValue.type === "ARRAY_REMOVE") {
let values = Array.isArray(fieldValue.value[0]) ? fieldValue.value[0] : fieldValue.value;
values = values.map(v => typeof (v) === "object" ? firebase.toHashMap(v) : v);
node.put(property, com.google.firebase.firestore.FieldValue.arrayRemove(values));
}
else if (fieldValue.type === "INCREMENT") {
node.put(property, com.google.firebase.firestore.FieldValue.increment(fieldValue.value));
}
else {
console.log("You found a bug! Please report an issue at https://github.com/EddyVerbruggen/nativescript-plugin-firebase/issues, mention fieldValue.type = '" + fieldValue.type + "'. Thanks!");
}
}
else if (obj[property] instanceof Date) {
node.put(property, new java.util.Date(obj[property].getTime()));
}
else if (obj[property] instanceof GeoPoint) {
const geo = obj[property];
node.put(property, new com.google.firebase.firestore.GeoPoint(geo.latitude, geo.longitude));
}
else if (isDocumentReference(obj[property])) {
node.put(property, obj[property].android);
}
else if (Array.isArray(obj[property])) {
node.put(property, firebase.toJavaArray(obj[property]));
}
else {
switch (typeof obj[property]) {
case 'object':
node.put(property, firebase.toHashMap(obj[property], node));
break;
case 'boolean':
node.put(property, java.lang.Boolean.valueOf(String(obj[property])));
break;
case 'number':
if (Number(obj[property]) === obj[property] && obj[property] % 1 === 0)
node.put(property, java.lang.Long.valueOf(String(obj[property])));
else
node.put(property, java.lang.Double.valueOf(String(obj[property])));
break;
case 'string':
node.put(property, String(obj[property]));
break;
}
}
}
}
}
return node;
};
firebase.toJavaArray = val => {
const javaArray = new java.util.ArrayList();
for (let i = 0; i < val.length; i++) {
javaArray.add(firebase.toValue(val[i]));
}
return javaArray;
};
firebase.toValue = val => {
let returnVal = null;
if (val !== null) {
if (val instanceof Date) {
returnVal = new java.util.Date(val.getTime());
}
else if (Array.isArray(val)) {
returnVal = firebase.toJavaArray(val);
}
else if (val instanceof GeoPoint) {
returnVal = new com.google.firebase.firestore.GeoPoint(val.latitude, val.longitude);
}
else if (isDocumentReference(val)) {
returnVal = val.android;
}
else {
switch (typeof val) {
case 'object':
returnVal = firebase.toHashMap(val);
break;
case 'boolean':
returnVal = java.lang.Boolean.valueOf(String(val));
break;
case 'number':
if (Number(val) === val && val % 1 === 0)
returnVal = java.lang.Long.valueOf(String(val));
else
returnVal = java.lang.Double.valueOf(String(val));
break;
case 'string':
returnVal = String(val);
break;
}
}
}
return returnVal;
};
firebase.toJsObject = javaObj => {
if (javaObj === null || typeof javaObj !== "object") {
return javaObj;
}
let node;
switch (javaObj.getClass().getName()) {
case 'java.lang.Boolean':
const str = String(javaObj);
return Boolean(!!(str === "True" || str === "true"));
case 'java.lang.String':
return String(javaObj);
case 'java.lang.Integer':
case 'java.lang.Long':
case 'java.lang.Double':
return Number(String(javaObj));
case 'java.util.Date':
return new Date(javaObj.getTime());
case 'com.google.firebase.Timestamp':
return new Date(javaObj.toDate().getTime());
case 'com.google.firebase.firestore.GeoPoint':
return {
"latitude": javaObj.getLatitude(),
"longitude": javaObj.getLongitude()
};
case 'com.google.firebase.firestore.DocumentReference':
const path = javaObj.getPath();
const lastSlashIndex = path.lastIndexOf("/");
return firebase.firestore._getDocumentReference(javaObj, path.substring(0, lastSlashIndex), path.substring(lastSlashIndex + 1));
case 'java.util.ArrayList':
node = [];
for (let i = 0; i < javaObj.size(); i++) {
node[i] = firebase.toJsObject(javaObj.get(i));
}
break;
case 'android.util.ArrayMap':
case 'android.support.v4.util.ArrayMap':
case 'androidx.collection.ArrayMap':
node = {};
for (let i = 0; i < javaObj.size(); i++) {
node[javaObj.keyAt(i)] = firebase.toJsObject(javaObj.valueAt(i));
}
break;
default:
try {
node = {};
const iterator = javaObj.entrySet().iterator();
while (iterator.hasNext()) {
const item = iterator.next();
node[item.getKey()] = firebase.toJsObject(item.getValue());
}
}
catch (e) {
if (JSON.stringify(e).includes("Attempt to use cleared object reference")) {
console.log("Error while transforming Java to Js: " + e);
}
else {
console.log("PLEASE REPORT THIS AT https://github.com/EddyVerbruggen/nativescript-plugin-firebase/issues: Tried to serialize an unsupported type: " + javaObj.getClass().getName() + ", error: " + e);
}
}
}
return node;
};
firebase.getCallbackData = (type, snapshot) => {
return {
type: type,
key: snapshot.getKey(),
value: firebase.toJsObject(snapshot.getValue())
};
};
firebase.authStateListener = null;
firebase.init = arg => {
return new Promise((resolve, reject) => {
if (firebase.initialized) {
reject("Firebase already initialized");
return;
}
firebase.initialized = true;
const runInit = () => {
arg = arg || {};
initializeArguments = arg;
if (typeof (com.google.firebase.analytics) !== "undefined" && typeof (com.google.firebase.analytics.FirebaseAnalytics) !== "undefined") {
com.google.firebase.analytics.FirebaseAnalytics.getInstance(Application.android.context || Application.getNativeApplication()).setAnalyticsCollectionEnabled(arg.analyticsCollectionEnabled !== false);
}
if (typeof (com.google.firebase.database) !== "undefined" && typeof (com.google.firebase.database.ServerValue) !== "undefined") {
firebase.ServerValue = {
TIMESTAMP: firebase.toJsObject(com.google.firebase.database.ServerValue.TIMESTAMP)
};
const fDatabase = com.google.firebase.database.FirebaseDatabase;
if (arg.persist) {
try {
fDatabase.getInstance().setPersistenceEnabled(true);
}
catch (ignore) {
}
}
firebase.instance = fDatabase.getInstance().getReference();
}
if (arg.persist === false && typeof (com.google.firebase.firestore) !== "undefined") {
try {
com.google.firebase.firestore.FirebaseFirestore.getInstance().setFirestoreSettings(new com.google.firebase.firestore.FirebaseFirestoreSettings.Builder()
.setPersistenceEnabled(false)
.build());
}
catch (ignore) {
}
}
if (authEnabled()) {
const firebaseAuth = com.google.firebase.auth.FirebaseAuth.getInstance();
if (arg.onAuthStateChanged) {
firebase.addAuthStateListener(arg.onAuthStateChanged);
}
if (!firebase.authStateListener) {
firebase.authStateListener = new com.google.firebase.auth.FirebaseAuth.AuthStateListener({
onAuthStateChanged: fbAuth => {
const user = fbAuth.getCurrentUser();
firebase.notifyAuthStateListeners({
loggedIn: user !== null,
user: toLoginResult(user)
});
}
});
firebaseAuth.addAuthStateListener(firebase.authStateListener);
}
}
if (messagingEnabled()) {
firebaseMessaging.initFirebaseMessaging(arg);
}
if (arg.onDynamicLinkCallback !== undefined) {
firebase.addOnDynamicLinkReceivedCallback(arg.onDynamicLinkCallback);
}
if (arg.storageBucket) {
if (typeof (com.google.firebase.storage) === "undefined") {
reject("Uncomment firebase-storage in the plugin's include.gradle first");
return;
}
firebase.storageBucket = com.google.firebase.storage.FirebaseStorage.getInstance().getReferenceFromUrl(arg.storageBucket);
}
if (typeof (gmsAds) !== "undefined" && typeof (gmsAds.MobileAds) !== "undefined") {
gmsAds.MobileAds.initialize(Application.android.context);
}
resolve(firebase.instance);
};
try {
if (Application.android.startActivity) {
runInit();
}
else {
Application.on(Application.launchEvent, runInit);
}
}
catch (ex) {
console.log("Error in firebase.init: " + ex);
reject(ex);
}
});
};
firebase.fetchSignInMethodsForEmail = email => {
return new Promise((resolve, reject) => {
try {
if (typeof (email) !== "string") {
reject("A parameter representing an email address is required.");
return;
}
const onCompleteListener = new gmsTasks.OnCompleteListener({
onComplete: task => {
if (!task.isSuccessful()) {
reject((task.getException() && task.getException().getReason ? task.getException().getReason() : task.getException()));
}
else {
const signInMethods = task.getResult().getSignInMethods();
resolve(firebase.toJsObject(signInMethods));
}
}
});
com.google.firebase.auth.FirebaseAuth.getInstance().fetchSignInMethodsForEmail(email).addOnCompleteListener(onCompleteListener);
}
catch (ex) {
console.log("Error in firebase.fetchSignInMethodsForEmail: " + ex);
reject(ex);
}
});
};
firebase.getCurrentPushToken = firebaseMessaging.getCurrentPushToken;
firebase.addOnMessageReceivedCallback = firebaseMessaging.addOnMessageReceivedCallback;
firebase.addOnPushTokenReceivedCallback = firebaseMessaging.addOnPushTokenReceivedCallback;
firebase.registerForPushNotifications = firebaseMessaging.registerForPushNotifications;
firebase.unregisterForPushNotifications = firebaseMessaging.unregisterForPushNotifications;
firebase.subscribeToTopic = firebaseMessaging.subscribeToTopic;
firebase.unsubscribeFromTopic = firebaseMessaging.unsubscribeFromTopic;
firebase.areNotificationsEnabled = firebaseMessaging.areNotificationsEnabled;
firebase.functions = firebaseFunctions;
firebase.addOnEmailLinkError = callback => {
firebase._emailLinkErrorCallback = callback;
};
firebase.addOnDynamicLinkReceivedCallback = callback => {
return new Promise((resolve, reject) => {
try {
if (typeof (com.google.firebase.dynamiclinks) === "undefined") {
reject("Uncomment dynamic links in the plugin's include.gradle first");
return;
}
firebase._dynamicLinkCallback = callback;
if (firebase._cachedDynamicLink !== null) {
callback(firebase._cachedDynamicLink);
firebase._cachedDynamicLink = null;
}
resolve();
}
catch (ex) {
console.log("Error in firebase.addOnDynamicLinkReceivedCallback: " + ex);
reject(ex);
}
});
};
firebase.getRemoteConfigDefaults = properties => {
let defaults = {};
for (const p in properties) {
const prop = properties[p];
if (prop.default !== undefined) {
defaults[prop.key] = prop.default;
}
}
return defaults;
};
firebase._isGooglePlayServicesAvailable = () => {
const ctx = Application.android.foregroundActivity || Application.android.startActivity || Application.getNativeApplication();
const googleApiAvailability = com.google.android.gms.common.GoogleApiAvailability.getInstance();
const playServiceStatusSuccess = 0;
const playServicesStatus = googleApiAvailability.isGooglePlayServicesAvailable(ctx);
const available = playServicesStatus === playServiceStatusSuccess;
if (!available && googleApiAvailability.isUserResolvableError(playServicesStatus)) {
googleApiAvailability.showErrorDialogFragment(ctx, playServicesStatus, 1, new android.content.DialogInterface.OnCancelListener({
onCancel: dialogInterface => {
console.log("Canceled");
}
}));
}
return available;
};
firebase.getRemoteConfig = arg => {
return new Promise((resolve, reject) => {
if (typeof (com.google.firebase.remoteconfig) === "undefined") {
reject("Uncomment firebase-config in the plugin's include.gradle first");
return;
}
if (arg.properties === undefined) {
reject("Argument 'properties' is missing");
return;
}
const runGetRemoteConfig = () => {
if (!firebase._isGooglePlayServicesAvailable()) {
reject("Google Play services is required for this feature, but not available on this device");
return;
}
const firebaseRemoteConfig = com.google.firebase.remoteconfig.FirebaseRemoteConfig.getInstance();
const remoteConfigSettingsBuilder = new com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings.Builder();
if (arg.developerMode === true) {
remoteConfigSettingsBuilder.setFetchTimeoutInSeconds(0);
}
const onSetConfigSettingsCompleteListener = new gmsTasks.OnCompleteListener({
onComplete: task => {
if (!task.isSuccessful()) {
reject((task.getException() && task.getException().getReason ? task.getException().getReason() : task.getException()));
}
else {
const defaults = firebase.getRemoteConfigDefaults(arg.properties);
firebaseRemoteConfig.setDefaultsAsync(firebase.toHashMap(defaults))
.addOnCompleteListener(new gmsTasks.OnCompleteListener({
onComplete: task => {
if (!task.isSuccessful()) {
reject((task.getException() && task.getException().getReason ? task.getException().getReason() : task.getException()));
}
else {
const returnMethod = throttled => {
const addOnCompleteActivateListener = new gmsTasks.OnCompleteListener({
onComplete: task => {
if (!task.isSuccessful()) {
reject((task.getException() && task.getException().getReason ? task.getException().getReason() : task.getException()));
}
else {
const lastFetchTime = firebaseRemoteConfig.getInfo().getFetchTimeMillis();
const lastFetch = new Date(lastFetchTime);
const result = {
lastFetch,
throttled,
properties: {}
};
for (const p in arg.properties) {
const prop = arg.properties[p];
const key = prop.key;
const value = firebaseRemoteConfig.getString(key);
result.properties[key] = firebase.strongTypeify(value);
}
resolve(result);
}
}
});
firebaseRemoteConfig.activate().addOnCompleteListener(addOnCompleteActivateListener);
};
const onSuccessListener = new gmsTasks.OnSuccessListener({
onSuccess: () => returnMethod(false)
});
const onFailureListener = new gmsTasks.OnFailureListener({
onFailure: exception => {
if (exception.getMessage() === "com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException") {
returnMethod(true);
}
else {
reject("Retrieving remote config data failed. " + exception);
}
}
});
const expirationDuration = arg.cacheExpirationSeconds || 43200;
firebaseRemoteConfig.fetch(expirationDuration)
.addOnSuccessListener(onSuccessListener)
.addOnFailureListener(onFailureListener);
}
}
}));
}
}
});
firebaseRemoteConfig.setConfigSettingsAsync(remoteConfigSettingsBuilder.build())
.addOnCompleteListener(onSetConfigSettingsCompleteListener);
};
try {
if (Application.android.foregroundActivity) {
runGetRemoteConfig();
}
else {
const callback = () => {
runGetRemoteConfig();
Application.off(Application.resumeEvent, callback);
};
Application.on(Application.resumeEvent, callback);
}
}
catch (ex) {
console.log("Error in firebase.getRemoteConfig: " + ex);
reject(ex);
}
});
};
firebase.getCurrentUser = arg => {
return new Promise((resolve, reject) => {
try {
const firebaseAuth = com.google.firebase.auth.FirebaseAuth.getInstance();
const user = firebaseAuth.getCurrentUser();
if (user !== null) {
resolve(toLoginResult(user));
}
else {
reject();
}
}
catch (ex) {
console.log("Error in firebase.getCurrentUser: " + ex);
reject(ex);
}
});
};
firebase.sendEmailVerification = (actionCodeSettings) => {
return new Promise((resolve, reject) => {
try {
const firebaseAuth = com.google.firebase.auth.FirebaseAuth.getInstance();
const user = firebaseAuth.getCurrentUser();
if (user !== null) {
const addOnCompleteListener = new gmsTasks.OnCompleteListener({
onComplete: task => {
if (!task.isSuccessful()) {
reject((task.getException() && task.getException().getReason ? task.getException().getReason() : task.getException()));
}
else {
resolve();
}
}
});
if (actionCodeSettings) {
const settingsBuilder = new com.google.firebase.auth.ActionCodeSettings.newBuilder();
if (actionCodeSettings.handleCodeInApp !== undefined) {
settingsBuilder.setHandleCodeInApp(actionCodeSettings.handleCodeInApp);
}
if (actionCodeSettings.url) {
settingsBuilder.setUrl(actionCodeSettings.url);
}
if (actionCodeSettings.iOS && actionCodeSettings.iOS.bundleId) {
settingsBuilder.setIOSBundleId(actionCodeSettings.iOS.bundleId);
}
if (actionCodeSettings.android && actionCodeSettings.android.packageName) {
settingsBuilder.setAndroidPackageName(actionCodeSettings.android.packageName, actionCodeSettings.android.installApp, actionCodeSettings.android.minimumVersion || null);
}
user.sendEmailVerification(settingsBuilder.build()).addOnCompleteListener(addOnCompleteListener);
}
else {
user.sendEmailVerification().addOnCompleteListener(addOnCompleteListener);
}
}
else {
reject("Log in first");
}
}
catch (ex) {
console.log("Error in firebase.sendEmailVerification: " + ex);
reject(ex);
}
});
};
firebase.logout = arg => {
return new Promise((resolve, reject) => {
try {
com.google.firebase.auth.FirebaseAuth.getInstance().signOut();
firebase.currentAdditionalUserInfo = null;
if (firebase._mGoogleApiClient && firebase._mGoogleApiClient.isConnected()) {
com.google.android.gms.auth.api.Auth.GoogleSignInApi.revokeAccess(firebase._mGoogleApiClient);
}
if (typeof (com.facebook) !== "undefined" && typeof (com.facebook.login) !== "undefined") {
com.facebook.login.LoginManager.getInstance().logOut();
}
resolve();
}
catch (ex) {
console.log("Error in firebase.logout: " + ex);
reject(ex);
}
});
};
firebase.unlink = providerId => {
return new Promise((resolve, reject) => {
try {
const user = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser();
if (!user) {
reject("Not logged in");
return;
}
user.unlink(providerId)
.addOnCompleteListener(new gmsTasks.OnCompleteListener({
onComplete: task => {
if (task.isSuccessful()) {
resolve();
}
else {
reject((task.getException() && task.getException().getReason ? task.getException().getReason() : task.getException()));
}
}
}));
}
catch (ex) {
console.log("Error in firebase.unlink: " + ex);
reject(ex);
}
});
};
firebase.getAuthToken = (arg) => {
return new Promise((resolve, reject) => {
try {
const firebaseAuth = com.google.firebase.auth.FirebaseAuth.getInstance();
const user = firebaseAuth.getCurrentUser();
if (user !== null) {
const onSuccessListener = new gmsTasks.OnSuccessListener({
onSuccess: tokenResult => {
resolve({
token: tokenResult.getToken(),
claims: firebase.toJsObject(tokenResult.getClaims()),
signInProvider: tokenResult.getSignInProvider(),
expirationTime: tokenResult.getExpirationTimestamp(),
issuedAtTime: tokenResult.getIssuedAtTimestamp(),
authTime: tokenResult.getAuthTimestamp()
});
}
});
const onFailureListener = new gmsTasks.OnFailureListener({
onFailure: exception => {
reject(exception);
}
});
user.getIdToken(arg.forceRefresh)
.addOnSuccessListener(onSuccessListener)
.addOnFailureListener(onFailureListener);
}
else {
reject("Log in first");
}
}
catch (ex) {
console.log("Error in firebase.getAuthToken: " + ex);
reject(ex);
}
});
};
function toLoginResult(user, additionalUserInfo) {
if (user === null) {
return null;
}
if (additionalUserInfo) {
firebase.currentAdditionalUserInfo = additionalUserInfo;
}
const providers = [];
const providerData = user.getProviderData();
for (let i = 0; i < providerData.size(); i++) {
const pid = providerData.get(i).getProviderId();
if (pid === 'facebook.com') {
providers.push({ id: pid, token: firebase._facebookAccessToken });
}
else if (pid === 'google.com') {
providers.push({ id: pid, token: firebase._googleSignInIdToken, code: firebase._googleSignInServerAuthCode });
}
else if (pid === 'apple.com') {
providers.push({ id: pid, token: firebase._appleSignInIdToken });
}
else {
providers.push({ id: pid });
}
}
const loginResult = {
uid: user.getUid(),
displayName: user.getDisplayName(),
email: user.getEmail(),
emailVerified: user.isEmailVerified(),
providers: providers,
anonymous: user.isAnonymous(),
isAnonymous: user.isAnonymous(),
phoneNumber: user.getPhoneNumber(),
photoURL: user.getPhotoUrl() ? user.getPhotoUrl().toString() : null,
metadata: {
creationTimestamp: user.getMetadata() ? new Date(user.getMetadata().getCreationTimestamp()) : null,
lastSignInTimestamp: user.getMetadata() ? new Date(user.getMetadata().getLastSignInTimestamp()) : null
},
getIdToken: (forceRefresh) => new Promise((resolve, reject) => {
firebase.getAuthToken({ forceRefresh })
.then((result) => resolve(result.token))
.catch(reject);
}),
getIdTokenResult: (forceRefresh) => new Promise((resolve, reject) => {
firebase.getAuthToken({ forceRefresh })
.then((result) => resolve(result))
.catch(reject);
}),
sendEmailVerification: (actionCodeSettings) => firebase.sendEmailVerification(actionCodeSettings)
};
if (firebase.currentAdditionalUserInfo) {
loginResult.additionalUserInfo = {
providerId: firebase.currentAdditionalUserInfo.getProviderId(),
username: firebase.currentAdditionalUserInfo.getUsername(),
isNewUser: firebase.currentAdditionalUserInfo.isNewUser(),
profile: firebase.toJsObject(firebase.currentAdditionalUserInfo.getProfile())
};
}
return loginResult;
}
firebase.login = arg => {
return new Promise((resolve, reject) => {
try {
firebase.resolve = resolve;
firebase.reject = reject;
if (!firebase._isGooglePlayServicesAvailable()) {
reject("Google Play services is required for this feature, but not available on this device");
return;
}
firebase.moveLoginOptionsToObjects(arg);
const firebaseAuth = com.google.firebase.auth.FirebaseAuth.getInstance();
const onCompleteListener = new gmsTasks.OnCompleteListener({
onComplete: task => {
if (!task.isSuccessful()) {
console.log("Logging in the user failed. " + (task.getException() && task.getException().getReason ? task.getException().getReason() : task.getException()));
if (firebase._mGoogleApiClient) {
com.google.android.gms.auth.api.Auth.GoogleSignInApi.revokeAccess(firebase._mGoogleApiClient);
}
if (firebase.reject) {
firebase.reject("Logging in the user failed. " + (task.getException() && task.getException().getReason ? task.getException().getReason() : task.getException()));
}
}
else {
const user = task.getResult().getUser();
let additionalUserInfo = task.getResult().getAdditionalUserInfo();
if (firebase.resolve) {
firebase.resolve(toLoginResult(user, additionalUserInfo));
}
}
}
});
if (arg.type === firebase.LoginType.ANONYMOUS) {
firebaseAuth.signInAnonymously().addOnCompleteListener(onCompleteListener);
}
else if (arg.type === firebase.LoginType.PASSWORD) {
if (!arg.passwordOptions || !arg.passwordOptions.email || !arg.passwordOptions.password) {
reject("Auth type PASSWORD requires an 'passwordOptions.email' and 'passwordOptions.password' argument");
return;
}
const user = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser();
if (user) {
if (firebase._alreadyLinkedToAuthProvider(user, "password")) {
firebaseAuth.signInWithEmailAndPassword(arg.passwordOptions.email, arg.passwordOptions.password).addOnCompleteListener(onCompleteListener);
}
else {
const authCredential = com.google.firebase.auth.EmailAuthProvider.getCredential(arg.passwordOptions.email, arg.passwordOptions.password);
user.linkWithCredential(authCredential).addOnCompleteListener(onCompleteListener);
}
}
else {
firebaseAuth.signInWithEmailAndPassword(arg.passwordOptions.email, arg.passwordOptions.password).addOnCompleteListener(onCompleteListener);
}
}
else if (arg.type === firebase.LoginType.EMAIL_LINK) {
if (!arg.emailLinkOptions || !arg.emailLinkOptions.email) {
reject("Auth type EMAIL_LINK requires an 'emailLinkOptions.email' argument");
return;
}
if (!arg.emailLinkOptions.url) {
reject("Auth type EMAIL_LINK requires an 'emailLinkOptions.url' argument");
return;
}
const newActionCodeSettingsBuilder = com.google.firebase.auth.ActionCodeSettings.newBuilder()
.setUrl(arg.emailLinkOptions.url)
.setHandleCodeInApp(true)
.setIOSBundleId(arg.emailLinkOptions.iOS ? arg.emailLinkOptions.iOS.bundleId : Application.android.context.getPackageName())
.setAndroidPackageName(arg.emailLinkOptions.android ? arg.emailLinkOptions.android.packageName : Application.android.context.getPackageName(), arg.emailLinkOptions.android ? arg.emailLinkOptions.android.installApp || false : false, arg.emailLinkOptions.android ? arg.emailLinkOptions.android.minimumVersion || "1" : "1");
if (arg.emailLinkOptions.dynamicLinkDomain) {
newActionCodeSettingsBuilder.setDynamicLinkDomain(arg.emailLinkOptions.dynamicLinkDomain);
}
const actionCodeSettings = newActionCodeSettingsBuilder.build();
const onEmailLinkCompleteListener = new gmsTasks.OnCompleteListener({
onComplete: task => {
if (!task.isSuccessful()) {
reject((task.getException() && task.getException().getReason ? task.getException().getReason() : task.getException()));
}
else {
firebase.rememberEmailForEmailLinkLogin(arg.emailLinkOptions.email);
resolve();
}
}
});
firebaseAuth.sendSignInLinkToEmail(arg.emailLinkOptions.email, actionCodeSettings).addOnCompleteListener(onEmailLinkCompleteListener);
}
else if (arg.type === firebase.LoginType.PHONE) {
if (!arg.phoneOptions || !arg.phoneOptions.phoneNumber) {
reject("Auth type PHONE requires a 'phoneOptions.phoneNumber' argument");
return;
}
const user = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser();
if (user && firebase._alreadyLinkedToAuthProvider(user, "phone")) {
resolve(toLoginResult(user));
return;
}
const OnVerificationStateChangedCallbacks = com.google.firebase.auth.PhoneAuthProvider.OnVerificationStateChangedCallbacks.extend({
onVerificationCompleted: phoneAuthCredential => {
firebase._verifyPhoneNumberInProgress = false;
const user = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser();
if (!user || firebase._alreadyLinkedToAuthProvider(user, "phone")) {
firebaseAuth.signInWithCredential(phoneAuthCredential).addOnCompleteListener(onCompleteListener);
}
else {
user.linkWithCredential(phoneAuthCredential).addOnCompleteListener(onCompleteListener);
}
},
onVerificationFailed: firebaseException => {
firebase._verifyPhoneNumberInProgress = false;
const errorMessage = firebaseException.getMessage();
if (errorMessage.includes("INVALID_APP_CREDENTIAL")) {
if (firebase.reject) {
firebase.reject("Please upload the SHA1 fingerprint of your debug and release keystores to the Firebase console, see https://github.com/EddyVerbruggen/nativescript-plugin-firebase/blob/master/docs/AUTHENTICATION.md#phone-verification");
}
}
else {
if (firebase.reject) {
firebase.reject(errorMessage);
}
}
},
onCodeSent: (verificationId, forceResendingToken) => {
setTimeout(() => {
if (firebase._verifyPhoneNumberInProgress) {
firebase._verifyPhoneNumberInProgress = false;
firebase.requestPhoneAuthVerificationCode(userResponse => {
if ((userResponse === undefined || userResponse === '') && firebase.reject) {
firebase.reject("Prompt was canceled");
return;
}
const authCredential = com.google.firebase.auth.PhoneAuthProvider.getCredential(verificationId, userResponse);
const user = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser();
if (!user || firebase._alreadyLinkedToAuthProvider(user, "phone")) {
firebaseAuth.signInWithCredential(authCredential).addOnCompleteListener(onCompleteListener);
}
else {
user.linkWithCredential(authCredential).addOnCompleteListener(onCompleteListener);
}
}, arg.phoneOptions.verificationPrompt);
}
}, 3000);
}
});
firebase._verifyPhoneNumberInProgress = true;
let timeout = arg.phoneOptions.android ? arg.phoneOptions.android.timeout : 60;
com.google.firebase.auth.PhoneAuthProvider.getInstance().verifyPhoneNumber(arg.phoneOptions.phoneNumber, timeout, java.util.concurrent.TimeUnit.SECONDS, Application.android.foregroundActivity, new OnVerificationStateChangedCallbacks());
}
else if (arg.type === firebase.LoginType.CUSTOM) {
if (!arg.customOptions || (!arg.customOptions.token && !arg.customOptions.tokenProviderFn)) {
reject("Auth type CUSTOM requires a 'customOptions.token' or 'customOptions.tokenProviderFn' argument");
return;
}
if (arg.customOptions.token) {
firebaseAuth.signInWithCustomToken(arg.customOptions.token).addOnCompleteListener(onCompleteListener);
}
else if (arg.customOptions.tokenProviderFn) {
arg.customOptions.tokenProviderFn()
.then(token => {
firebaseAuth.signInWithCustomToken(token).addOnCompleteListener(onCompleteListener);
}, error => {
reject(error);
});
}
}
else if (arg.type === firebase.LoginType.FACEBOOK) {
if (typeof (com.facebook) === "undefined" || typeof (com.facebook.FacebookSdk) === "undefined") {
reject("Facebook SDK not installed - see gradle config");
return;
}
if (!fbCallbackManager) {
com.facebook.FacebookSdk.sdkInitialize(Application.getNativeApplication());
fbCallbackManager = com.facebook.CallbackManager.Factory.create();
}
const callback = (eventData) => {
Application.android.off(AndroidApplication.activityResultEvent, callback);
fbCallbackManager.onActivityResult(eventData.requestCode, eventData.resultCode, eventData.intent);
};
Application.android.on(AndroidApplication.activityResultEvent, callback);
const fbLoginManager = com.facebook.login.LoginManager.getInstance();
fbLoginManager.registerCallback(fbCallbackManager, new com.facebook.FacebookCallback({
onSuccess: loginResult => {
firebase._facebookAccessToken = loginResult.getAccessToken().getToken();
const authCredential = com.google.firebase.auth.FacebookAuthProvider.getCredential(firebase._facebookAccessToken);
const user = com.google.firebase.auth.FirebaseAuth.getInstance().getCurrentUser();
if (user) {
if (firebase._alreadyLinkedToAuthProvider(user, "facebook.com")) {
firebaseAuth.signInWithCredential(authCredential).addOnCompleteListener(onCompleteListener);
}
else {
user.linkWithCredential(authCredential).addOnCompleteListener(onCompleteListener);
}
}
else {
firebaseAuth.signInWithCredential(authCredential).addOnCompleteListener(onCompleteListener);