UNPKG

nativescript-firebase-updated-new

Version:
984 lines (983 loc) 114 kB
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);