diff --git a/.gitignore b/.gitignore index 5a1a2e02..bb22f326 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,10 @@ package-lock.json *.js !src/*-hooks.js build/ +*.tgz *.log.* src/**/*.d.ts +src/**/*.map src/platforms/ios_lib/TNSMLKitCamera/TNSMLKitCamera.xcodeproj/project.xcworkspace src/platforms/ios_lib/TNSMLKitCamera/TNSMLKitCamera.xcodeproj/xcuserdata src/platforms/ios/Podfile diff --git a/demo/app/app.ts b/demo/app/app.ts index 02604dcf..13abbaa5 100644 --- a/demo/app/app.ts +++ b/demo/app/app.ts @@ -1,13 +1,11 @@ -import "./bundle-config"; -import * as application from "tns-core-modules/application"; -import { UnhandledErrorEventData } from "tns-core-modules/application"; +import { Application, UnhandledErrorEventData } from "@nativescript/core"; // added this here so we can do some wiring -require("nativescript-plugin-firebase"); +require("@nativescript/firebase"); // testing this.. we may be able to hook that up to Crashlytics. Either via docs, or automatically. -application.on(application.uncaughtErrorEvent, (args: UnhandledErrorEventData) => { +Application.on(Application.uncaughtErrorEvent, (args: UnhandledErrorEventData) => { console.log("[app.js]: Uncaught NativeScript Error: " + args.error); }); -application.run({ moduleName: "main-page" }); +Application.run({ moduleName: "main-page" }); diff --git a/demo/app/bundle-config.ts b/demo/app/bundle-config.ts deleted file mode 100644 index 436a04d5..00000000 --- a/demo/app/bundle-config.ts +++ /dev/null @@ -1,9 +0,0 @@ -if (global.TNS_WEBPACK) { - // registers tns-core-modules UI framework modules - require("bundle-entry-points"); - - // register application modules - // This will register each `page` postfixed xml, css, js, ts, scss etc. in the app/ folder - const context = require.context("~/", true, /(page|fragment)\.(xml|css|js|ts|scss|less|sass)$/); - global.registerWebpackModules(context); -} \ No newline at end of file diff --git a/demo/app/main-page.ts b/demo/app/main-page.ts index 77dd4d42..f88ddf6c 100644 --- a/demo/app/main-page.ts +++ b/demo/app/main-page.ts @@ -1,12 +1,11 @@ -import * as observable from "tns-core-modules/data/observable"; -import * as pages from "tns-core-modules/ui/page"; +import { EventData, Page } from "@nativescript/core"; import { HelloWorldModel } from "./main-view-model"; const model = new HelloWorldModel(); // Event handler for Page 'loaded' event attached in main-page.xml -export function pageLoaded(args: observable.EventData) { +export function pageLoaded(args: EventData) { // Get the event sender - let page = args.object; + let page = args.object; page.bindingContext = model; } diff --git a/demo/app/main-view-model.ts b/demo/app/main-view-model.ts index 9b22f86b..317be73c 100644 --- a/demo/app/main-view-model.ts +++ b/demo/app/main-view-model.ts @@ -1,15 +1,11 @@ -import * as firebase from "nativescript-plugin-firebase"; -import { AddEventListenerResult, admob as firebaseAdMob, crashlytics as firebaseCrashlytics, GetRemoteConfigResult, IdTokenResult, LogComplexEventTypeParameter, performance as firebasePerformance, storage as firebaseStorage, User } from "nativescript-plugin-firebase"; -import { RewardedVideoAdReward } from "nativescript-plugin-firebase/admob/admob"; -import { FirebaseTrace } from "nativescript-plugin-firebase/performance/performance"; -import { Observable } from "tns-core-modules/data/observable"; -import * as fs from "tns-core-modules/file-system"; -import { isAndroid, isIOS } from "tns-core-modules/platform"; -import { alert, prompt } from "tns-core-modules/ui/dialogs"; +import { firebase, AddEventListenerResult, admob as firebaseAdMob, crashlytics as firebaseCrashlytics, GetRemoteConfigResult, IdTokenResult, LogComplexEventTypeParameter, performance as firebasePerformance, storage as firebaseStorage, User } from "@nativescript/firebase"; +import { RewardedVideoAdReward } from "@nativescript/firebase/admob/admob"; +import { FirebaseTrace } from "@nativescript/firebase/performance/performance"; +import { Observable, isAndroid, isIOS, Dialogs, knownFolders, File } from "@nativescript/core"; import { UploadMetadata } from "../../src/storage/storage"; import { MessagingViewModel } from "./messaging-view-model"; -const firebaseWebApi = require("nativescript-plugin-firebase/app"); +const firebaseWebApi = require("@nativescript/firebase/app"); declare const Crashlytics: any; @@ -309,7 +305,7 @@ export class HelloWorldModel extends Observable { public doWebUploadFile(): void { // let's first create a File object using the tns file module - const appPath = fs.knownFolders.currentApp().path; + const appPath = knownFolders.currentApp().path; const logoPath = appPath + "/images/telerik-logo.png"; const storageRef = firebaseWebApi.storage().ref(); @@ -324,7 +320,7 @@ export class HelloWorldModel extends Observable { } }; - childRef.put(fs.File.fromPath(logoPath), metadata).then( + childRef.put(File.fromPath(logoPath), metadata).then( uploadedFile => { console.log("Uploaded! " + JSON.stringify(uploadedFile)); this.set("storageFeedback", "Uploaded!"); @@ -341,7 +337,7 @@ export class HelloWorldModel extends Observable { const childRef = storageRef.child("uploads/images/telerik-logo-uploaded.png"); // let's first determine where we'll create the file using the 'file-system' module - const documents = fs.knownFolders.documents(); + const documents = knownFolders.documents(); const logoPath = documents.path + "/telerik-logo-downloaded.png"; childRef.download(logoPath) @@ -1666,7 +1662,7 @@ export class HelloWorldModel extends Observable { public doUploadFile(): void { // let's first create a File object using the tns file module - const appPath = fs.knownFolders.currentApp().path; + const appPath = knownFolders.currentApp().path; const logoPath = appPath + "/images/telerik-logo.png"; const metadata: UploadMetadata = { @@ -1680,7 +1676,7 @@ export class HelloWorldModel extends Observable { firebaseStorage.uploadFile({ remoteFullPath: 'uploads/images/telerik-logo-uploaded.png', - localFile: fs.File.fromPath(logoPath), // use this (a file-system module File object) + localFile: File.fromPath(logoPath), // use this (a file-system module File object) // localFullPath: logoPath, // or this, a full file path onProgress: status => { console.log("Uploaded fraction: " + status.fractionCompleted + " (" + status.percentageCompleted + "%)"); @@ -1702,7 +1698,7 @@ export class HelloWorldModel extends Observable { public doDownloadFile(): void { // let's first determine where we'll create the file using the 'file-system' module - const documents = fs.knownFolders.documents(); + const documents = knownFolders.documents(); const logoPath = documents.path + "/telerik-logo-downloaded.png"; // this will create or overwrite a local file in the app's documents folder diff --git a/demo/app/messaging-view-model.ts b/demo/app/messaging-view-model.ts index 289898a6..2259f63c 100644 --- a/demo/app/messaging-view-model.ts +++ b/demo/app/messaging-view-model.ts @@ -1,7 +1,6 @@ -import { alert } from "tns-core-modules/ui/dialogs"; -import * as platform from "tns-core-modules/platform"; -import * as firebase from "nativescript-plugin-firebase"; -import { messaging } from "nativescript-plugin-firebase/messaging"; +import { Dialogs } from "@nativescript/core"; +import { firebase } from "@nativescript/firebase"; +import { messaging } from "@nativescript/firebase/messaging"; const getCircularReplacer = () => { const seen = new WeakSet; @@ -21,7 +20,7 @@ export class MessagingViewModel { firebase.getCurrentPushToken().then(token => { // may be null if not known yet console.log("Current push token: " + token); - alert({ + Dialogs.alert({ title: "Current Push Token", message: (token === null ? "Not received yet" : token + ("\n\nSee the console log if you want to copy-paste it.")), okButtonText: "OK, thx" @@ -30,7 +29,7 @@ export class MessagingViewModel { } public doRegisterForInteractivePush(): void { - if (platform.isIOS) { + if (global.isIOS) { const model = new messaging.PushNotificationModel(); model.iosSettings = new messaging.IosPushSettings(); model.iosSettings.badge = false; diff --git a/demo/app/package.json b/demo/app/package.json deleted file mode 100644 index 02795c2b..00000000 --- a/demo/app/package.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "name": "tns-template-hello-world-ts", - "main": "app.js", - "version": "1.6.0", - "author": { - "name": "Telerik", - "email": "support@telerik.com" - }, - "description": "Nativescript hello-world-ts project template", - "license": "Apache-2.0", - "keywords": [ - "telerik", - "mobile", - "nativescript", - "{N}", - "tns", - "appbuilder", - "template" - ], - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/NativeScript/template-hello-world-ts.git" - }, - "bugs": { - "url": "https://github.com/NativeScript/template-hello-world-ts/issues" - }, - "homepage": "https://github.com/NativeScript/template-hello-world-ts", - "android": { - "v8Flags": "--expose_gc", - "markingMode": "none" - }, - "discardUncaughtJsExceptions": false, - "devDependencies": { - "nativescript-dev-typescript": "^0.3.0" - }, - "_id": "tns-template-hello-world-ts@1.6.0", - "_shasum": "a567c2b9a56024818c06596dab9629d155c5b8a8", - "_resolved": "https://registry.npmjs.org/tns-template-hello-world-ts/-/tns-template-hello-world-ts-1.6.0.tgz", - "_from": "tns-template-hello-world-ts@latest", - "scripts": { - "build.plugin": "cd ../src && npm run build", - "ci.tslint": "npm i && tslint --config '../tslint.json' 'app/**/*.ts' --exclude '**/node_modules/**'" - }, - "_npmVersion": "2.14.7", - "_nodeVersion": "4.2.2", - "_npmUser": { - "name": "enchev", - "email": "vladimir.enchev@gmail.com" - }, - "dist": { - "shasum": "a567c2b9a56024818c06596dab9629d155c5b8a8", - "tarball": "http://registry.npmjs.org/tns-template-hello-world-ts/-/tns-template-hello-world-ts-1.6.0.tgz" - }, - "maintainers": [ - { - "name": "enchev", - "email": "vladimir.enchev@gmail.com" - }, - { - "name": "erjangavalji", - "email": "erjan.gavalji@gmail.com" - }, - { - "name": "fatme", - "email": "hfatme@gmail.com" - }, - { - "name": "hdeshev", - "email": "hristo@deshev.com" - }, - { - "name": "kerezov", - "email": "d.kerezov@gmail.com" - }, - { - "name": "ligaz", - "email": "stefan.dobrev@gmail.com" - }, - { - "name": "nsndeck", - "email": "nedyalko.nikolov@telerik.com" - }, - { - "name": "rosen-vladimirov", - "email": "rosen.vladimirov.91@gmail.com" - }, - { - "name": "sdobrev", - "email": "stefan.dobrev@gmail.com" - }, - { - "name": "tailsu", - "email": "tailsu@gmail.com" - }, - { - "name": "teobugslayer", - "email": "teobugslayer@gmail.com" - }, - { - "name": "valio.stoychev", - "email": "valio.stoychev@gmail.com" - } - ], - "_npmOperationalInternal": { - "host": "packages-5-east.internal.npmjs.com", - "tmp": "tmp/tns-template-hello-world-ts-1.6.0.tgz_1455717516189_0.6427943941671401" - }, - "directories": {}, - "readme": "ERROR: No README data found!" -} diff --git a/demo/app/tests/tests.native-api.ts b/demo/app/tests/tests.native-api.ts index 17e5aee6..7d99188d 100644 --- a/demo/app/tests/tests.native-api.ts +++ b/demo/app/tests/tests.native-api.ts @@ -1,4 +1,4 @@ -const firebase = require("nativescript-plugin-firebase"); +const firebase = require("@nativescript/firebase"); // TODO make this slightly more useful :P diff --git a/demo/app/tests/tests.web-api.ts b/demo/app/tests/tests.web-api.ts index f49d39eb..cf9b8114 100644 --- a/demo/app/tests/tests.web-api.ts +++ b/demo/app/tests/tests.web-api.ts @@ -1,4 +1,4 @@ -const firebaseWebApi = require("nativescript-plugin-firebase/app"); +const firebaseWebApi = require("@nativescript/firebase/app"); // TODO make this slightly more useful :P diff --git a/demo/nativescript.config.ts b/demo/nativescript.config.ts new file mode 100644 index 00000000..7c68e182 --- /dev/null +++ b/demo/nativescript.config.ts @@ -0,0 +1,12 @@ +import { NativeScriptConfig } from '@nativescript/core' + +export default { + id: 'org.nativescript.firebasedemo', + appResourcesPath: 'app_resources', + android: { + v8Flags: '--expose_gc', + markingMode: 'none', + }, + discardUncaughtJsExceptions: false, + appPath: 'app', +} as NativeScriptConfig diff --git a/demo/nsconfig.json b/demo/nsconfig.json deleted file mode 100644 index 01dbddfc..00000000 --- a/demo/nsconfig.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "appPath": "app", - "appResourcesPath": "app_resources" -} \ No newline at end of file diff --git a/demo/package.json b/demo/package.json index 431657a2..97ea3d4f 100644 --- a/demo/package.json +++ b/demo/package.json @@ -1,21 +1,15 @@ { - "nativescript": { - "id": "org.nativescript.firebasedemo", - "tns-ios": { - "version": "6.5.3" - }, - "tns-android": { - "version": "6.5.3" - } - }, "dependencies": { "firebase-functions": "^2.0.5", - "nativescript-plugin-firebase": "file:../publish/package/nativescript-plugin-firebase-10.6.0.tgz", + "@nativescript/firebase": "file:../src", "nativescript-theme-core": "^1.0.4", - "nativescript-unit-test-runner": "0.7.0", - "tns-core-modules": "~6.5.3" + "@nativescript/unit-test-runner": "~1.0.2", + "@nativescript/core": "7.0.0", + "@nativescript/webpack": "~3.0.0" }, "devDependencies": { + "@nativescript/ios": "7.0.4", + "@nativescript/types": "~7.0.0", "@types/jasmine": "~2.8.0", "babel-traverse": "6.12.0", "babel-types": "6.11.1", @@ -28,13 +22,12 @@ "karma-webpack": "3.0.5", "lazy": "1.0.11", "nativescript-css-loader": "~0.26.0", - "nativescript-dev-webpack": "1.0.1", - "tns-platform-declarations": "~6.5.3", "tslint": "~5.4.3", - "typescript": "3.4.5" + "typescript": "~4.0.0" }, "scripts": { "build.plugin": "cd ../src && npm run build", "ci.tslint": "npm i && tslint --config '../tslint.json' 'app/**/*.ts' --exclude '**/node_modules/**' --exclude '**/typings/**'" - } + }, + "main": "app.js" } diff --git a/demo/references.d.ts b/demo/references.d.ts index 5c2cbd67..df4cb14c 100644 --- a/demo/references.d.ts +++ b/demo/references.d.ts @@ -1,4 +1,2 @@ -/// -/// - +/// /// \ No newline at end of file diff --git a/demo/tsconfig.json b/demo/tsconfig.json index 3f44ba6a..b3f42531 100644 --- a/demo/tsconfig.json +++ b/demo/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "es5", - "module": "commonjs", + "target": "es2017", + "module": "esnext", "declaration": false, - "removeComments": true, + "removeComments": false, "noLib": false, "emitDecoratorMetadata": true, "experimentalDecorators": true, @@ -11,7 +11,8 @@ "lib": [ "es6", "dom", - "es2015.iterable" + "es2015.iterable", + "es2017" ], "pretty": true, "allowUnreachableCode": false, @@ -29,14 +30,11 @@ "types": [], "baseUrl": ".", "paths": { - "*": [ - "./node_modules/tns-core-modules/*", - "./node_modules/*" - ], "~/*": [ "app/*" ] - } + }, + "moduleResolution": "node" }, "exclude": [ "node_modules", diff --git a/demo/tsconfig.tns.json b/demo/tsconfig.tns.json deleted file mode 100644 index 95f2ecee..00000000 --- a/demo/tsconfig.tns.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig", - "compilerOptions": { - "module": "es2015", - "moduleResolution": "node" - } -} diff --git a/publish/scripts/installer.js b/publish/scripts/installer.js index 76b4a7a3..444baf1b 100755 --- a/publish/scripts/installer.js +++ b/publish/scripts/installer.js @@ -13,7 +13,7 @@ var directories = { console.log('NativeScript Firebase Plugin Installation'); -var appRoot = "../../"; +var appRoot = "../../../"; var pluginConfigFile = "firebase.nativescript.json"; var pluginConfigPath = path.join(appRoot, pluginConfigFile); var config = {}; diff --git a/src/.npmignore b/src/.npmignore index f7b6d114..a7be1dab 100644 --- a/src/.npmignore +++ b/src/.npmignore @@ -1,6 +1,7 @@ *.map *.ts !*.d.ts +ns-transform-native-classes.* tsconfig.json references.d.ts platforms/android/libraryproject/ @@ -11,3 +12,4 @@ platforms/android/typings/ platforms/web platforms/ios/Podfile platforms/android/include.gradle +*.tgz diff --git a/src/admob/admob.android.ts b/src/admob/admob.android.ts index daf82656..23fa17fc 100644 --- a/src/admob/admob.android.ts +++ b/src/admob/admob.android.ts @@ -1,9 +1,7 @@ import { firebase } from "../firebase-common"; import { BannerOptions, InterstitialOptions, PreloadRewardedVideoAdOptions, ShowRewardedVideoAdOptions } from "./admob"; import { AD_SIZE, BANNER_DEFAULTS, rewardedVideoCallbacks } from "./admob-common"; -import * as appModule from "tns-core-modules/application"; -import { topmost } from "tns-core-modules/ui/frame"; -import { layout } from "tns-core-modules/utils/utils"; +import { Application, Frame, Utils } from "@nativescript/core"; declare const com: any; @@ -22,7 +20,7 @@ export function showBanner(arg: BannerOptions): Promise { } } - firebase.admob.adView = new com.google.android.gms.ads.AdView(appModule.android.foregroundActivity); + firebase.admob.adView = new com.google.android.gms.ads.AdView(Application.android.foregroundActivity); firebase.admob.adView.setAdUnitId(settings.androidBannerId); const bannerType = _getBannerType(settings.size); firebase.admob.adView.setAdSize(bannerType); @@ -53,7 +51,7 @@ export function showBanner(arg: BannerOptions): Promise { const ad = _buildAdRequest(settings); firebase.admob.adView.loadAd(ad); - const density = layout.getDisplayDensity(), + const density = Utils.layout.getDisplayDensity(), top = settings.margins.top * density, bottom = settings.margins.bottom * density; @@ -71,21 +69,21 @@ export function showBanner(arg: BannerOptions): Promise { relativeLayoutParams.addRule(android.widget.RelativeLayout.ALIGN_PARENT_TOP); } - const adViewLayout = new android.widget.RelativeLayout(appModule.android.foregroundActivity); + const adViewLayout = new android.widget.RelativeLayout(Application.android.foregroundActivity); adViewLayout.addView(firebase.admob.adView, relativeLayoutParams); const relativeLayoutParamsOuter = new android.widget.RelativeLayout.LayoutParams( android.widget.RelativeLayout.LayoutParams.MATCH_PARENT, android.widget.RelativeLayout.LayoutParams.MATCH_PARENT); - // Wrapping it in a timeout makes sure that when this function is loaded from a Page.loaded event 'frame.topmost()' doesn't resolve to 'undefined'. + // Wrapping it in a timeout makes sure that when this function is loaded from a Page.loaded event 'frame.Frame.topmost()' doesn't resolve to 'undefined'. // Also, in NativeScript 4+ it may be undefined anyway.. so using the appModule in that case. setTimeout(() => { - const top = topmost(); + const top = Frame.topmost(); if (top !== undefined && top.currentPage && top.currentPage.android && top.currentPage.android.getParent()) { top.currentPage.android.getParent().addView(adViewLayout, relativeLayoutParamsOuter); - } else if (appModule.android && appModule.android.foregroundActivity) { - appModule.android.foregroundActivity.getWindow().getDecorView().addView(adViewLayout, relativeLayoutParamsOuter); + } else if (Application.android && Application.android.foregroundActivity) { + Application.android.foregroundActivity.getWindow().getDecorView().addView(adViewLayout, relativeLayoutParamsOuter); } else { console.log("Could not find a view to add the banner to"); } @@ -101,7 +99,7 @@ export function preloadInterstitial(arg: InterstitialOptions): Promise { return new Promise((resolve, reject) => { try { const settings = firebase.merge(arg, BANNER_DEFAULTS); - const activity = appModule.android.foregroundActivity || appModule.android.startActivity; + const activity = Application.android.foregroundActivity || Application.android.startActivity; firebase.admob.interstitialView = new com.google.android.gms.ads.InterstitialAd(activity); firebase.admob.interstitialView.setAdUnitId(settings.androidInterstitialId); @@ -152,7 +150,7 @@ export function showInterstitial(arg?: InterstitialOptions): Promise { } const settings = firebase.merge(arg, BANNER_DEFAULTS); - const activity = appModule.android.foregroundActivity || appModule.android.startActivity; + const activity = Application.android.foregroundActivity || Application.android.startActivity; firebase.admob.interstitialView = new com.google.android.gms.ads.InterstitialAd(activity); firebase.admob.interstitialView.setAdUnitId(settings.androidInterstitialId); @@ -192,7 +190,7 @@ export function preloadRewardedVideoAd(arg: PreloadRewardedVideoAdOptions): Prom return new Promise((resolve, reject) => { try { const settings = firebase.merge(arg, BANNER_DEFAULTS); - const activity = appModule.android.foregroundActivity || appModule.android.startActivity; + const activity = Application.android.foregroundActivity || Application.android.startActivity; firebase.admob.rewardedAdVideoView = com.google.android.gms.ads.MobileAds.getRewardedVideoAdInstance(activity); rewardedVideoCallbacks.onLoaded = resolve; @@ -326,7 +324,7 @@ function _buildAdRequest(settings): any { if (settings.testing) { builder.addTestDevice(com.google.android.gms.ads.AdRequest.DEVICE_ID_EMULATOR); // This will request test ads on the emulator and device by passing this hashed device ID. - const activity = appModule.android.foregroundActivity || appModule.android.startActivity; + const activity = Application.android.foregroundActivity || Application.android.startActivity; const ANDROID_ID = android.provider.Settings.Secure.getString(activity.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID); let deviceId = _md5(ANDROID_ID); if (deviceId !== null) { diff --git a/src/admob/admob.ios.ts b/src/admob/admob.ios.ts index 857be88a..7dc27ff8 100644 --- a/src/admob/admob.ios.ts +++ b/src/admob/admob.ios.ts @@ -1,5 +1,4 @@ -import { device } from "tns-core-modules/platform/platform"; -import { DeviceType } from "tns-core-modules/ui/enums/enums"; +import { Device, Enums } from "@nativescript/core"; import { firebase } from "../firebase-common"; import { BannerOptions, InterstitialOptions, PreloadRewardedVideoAdOptions, ShowRewardedVideoAdOptions } from "./admob"; import { AD_SIZE, BANNER_DEFAULTS, rewardedVideoCallbacks } from "./admob-common"; @@ -330,7 +329,7 @@ function _getBannerType(size): any { return {"size": {"width": 120, "height": 600}, "flags": 0}; } else if (size === AD_SIZE.SMART_BANNER || size === AD_SIZE.FLUID) { const orientation = UIDevice.currentDevice.orientation; - const isIPad = device.deviceType === DeviceType.Tablet; + const isIPad = Device.deviceType === Enums.DeviceType.Tablet; if (orientation === UIDeviceOrientation.Portrait || orientation === UIDeviceOrientation.PortraitUpsideDown) { // return kGADAdSizeSmartBannerPortrait; return {"size": {"width": 0, "height": 0, "smartHeight": isIPad ? 90 : 50}, "flags": 18}; @@ -344,6 +343,7 @@ function _getBannerType(size): any { } } +@NativeClass() class GADInterstitialDelegateImpl extends NSObject implements GADInterstitialDelegate { public static ObjCProtocols = []; private options: InterstitialOptions; @@ -382,6 +382,7 @@ class GADInterstitialDelegateImpl extends NSObject implements GADInterstitialDel } } +@NativeClass() class GADBannerViewDelegateImpl extends NSObject implements GADBannerViewDelegate { public static ObjCProtocols = []; private onAdCloseCallback: () => void; @@ -420,6 +421,7 @@ class GADBannerViewDelegateImpl extends NSObject implements GADBannerViewDelegat } } +@NativeClass() class GADRewardBasedVideoAdDelegateImpl extends NSObject implements GADRewardBasedVideoAdDelegate { public static ObjCProtocols = []; _loaded: () => void; diff --git a/src/analytics/analytics.android.ts b/src/analytics/analytics.android.ts index 7a4fd8ce..5da2b2e5 100644 --- a/src/analytics/analytics.android.ts +++ b/src/analytics/analytics.android.ts @@ -1,4 +1,4 @@ -import * as appModule from "tns-core-modules/application"; +import { Application } from "@nativescript/core"; import { LogComplexEventOptions, LogComplexEventParameter, LogEventOptions, SetScreenNameOptions, SetUserPropertyOptions } from "./analytics"; import { ENABLE_ANALYTICS_HINT, validateAnalyticsKey, validateAnalyticsParam } from "./analytics-common"; @@ -35,7 +35,7 @@ export function logEvent(options: LogEventOptions): Promise { } com.google.firebase.analytics.FirebaseAnalytics.getInstance( - appModule.android.context || appModule.getNativeApplication() + Application.android.context || Application.getNativeApplication() ).logEvent(options.key, bundle); resolve(); @@ -65,7 +65,7 @@ export function logComplexEvent(options: LogComplexEventOptions): Promise } com.google.firebase.analytics.FirebaseAnalytics.getInstance( - appModule.android.context || appModule.getNativeApplication() + Application.android.context || Application.getNativeApplication() ).logEvent(options.key, bundle); resolve(); @@ -90,7 +90,7 @@ export function setUserId(arg): Promise { } com.google.firebase.analytics.FirebaseAnalytics.getInstance( - appModule.android.context || appModule.getNativeApplication()).setUserId(arg.userId); + Application.android.context || Application.getNativeApplication()).setUserId(arg.userId); resolve(); } catch (ex) { @@ -118,7 +118,7 @@ export function setUserProperty(options: SetUserPropertyOptions): Promise } com.google.firebase.analytics.FirebaseAnalytics.getInstance( - appModule.android.context || appModule.getNativeApplication() + Application.android.context || Application.getNativeApplication() ).setUserProperty(options.key, options.value); resolve(); @@ -143,8 +143,8 @@ export function setScreenName(options: SetScreenNameOptions): Promise { } com.google.firebase.analytics.FirebaseAnalytics.getInstance( - appModule.android.context || appModule.getNativeApplication() - ).setCurrentScreen(appModule.android.foregroundActivity, options.screenName, null); + Application.android.context || Application.getNativeApplication() + ).setCurrentScreen(Application.android.foregroundActivity, options.screenName, null); resolve(); } catch (ex) { @@ -157,7 +157,7 @@ export function setScreenName(options: SetScreenNameOptions): Promise { export function setAnalyticsCollectionEnabled(enabled: boolean): void { if (isAnalyticsAvailable()) { com.google.firebase.analytics.FirebaseAnalytics.getInstance( - appModule.android.context || appModule.getNativeApplication() + Application.android.context || Application.getNativeApplication() ).setAnalyticsCollectionEnabled(enabled); } } @@ -165,7 +165,7 @@ export function setAnalyticsCollectionEnabled(enabled: boolean): void { export function setSessionTimeoutDuration(seconds: number): void { if (isAnalyticsAvailable()) { com.google.firebase.analytics.FirebaseAnalytics.getInstance( - appModule.android.context || appModule.getNativeApplication() + Application.android.context || Application.getNativeApplication() ).setSessionTimeoutDuration(seconds * 1000); // Android expects ms } } diff --git a/src/app/auth/index.ts b/src/app/auth/index.ts index dd237687..a837fb51 100644 --- a/src/app/auth/index.ts +++ b/src/app/auth/index.ts @@ -1,17 +1,16 @@ -import * as firebase from "../../firebase"; -import { FirebaseEmailLinkActionCodeSettings, LoginType, User, Unsubscribe } from "../../firebase"; +import { firebase } from "../../firebase"; export namespace auth { export class Auth { private authStateChangedHandler; private authStateOnErrorHandler; - public currentUser: User; + public currentUser: firebase.User; public languageCode: string | null; private loginHelper(options: firebase.LoginOptions) { return new Promise((resolve, reject) => { firebase.login(options) - .then((user: User) => { + .then((user: firebase.User) => { this.currentUser = user; this.authStateChangedHandler && this.authStateChangedHandler(user); resolve({ @@ -45,7 +44,7 @@ export namespace auth { // Completed will never be called, but it is here to closely follow the web api interface. // When called, the callback handler will be passed in the currentUser or undefined if not signed in - public onAuthStateChanged(handler: (user: User) => void, error?: (err) => any, completed?: Unsubscribe): Unsubscribe { + public onAuthStateChanged(handler: (user: firebase.User) => void, error?: (err) => any, completed?: firebase.Unsubscribe): firebase.Unsubscribe { this.authStateChangedHandler = handler; if (error) this.authStateOnErrorHandler = error; console.log(">> added onAuthStateChanged handler"); @@ -92,7 +91,7 @@ export namespace auth { public signInWithEmailAndPassword(email: string, password: string): Promise { const emailOption: firebase.LoginOptions = { - type: LoginType.PASSWORD, + type: firebase.LoginType.PASSWORD, passwordOptions: { email: email, password: password @@ -103,7 +102,7 @@ export namespace auth { public signInWithCustomToken(token: string): Promise { const customTokenOption: firebase.LoginOptions = { - type: LoginType.CUSTOM, + type: firebase.LoginType.CUSTOM, customOptions: { token: token } @@ -113,14 +112,14 @@ export namespace auth { public signInAnonymously(): Promise { const anonymousOption: firebase.LoginOptions = { - type: LoginType.ANONYMOUS + type: firebase.LoginType.ANONYMOUS }; return this.loginHelper(anonymousOption); } - public sendSignInLinkToEmail(email: string, actionCodeSettings: FirebaseEmailLinkActionCodeSettings): Promise { + public sendSignInLinkToEmail(email: string, actionCodeSettings: firebase.FirebaseEmailLinkActionCodeSettings): Promise { const sendSignInLinklOption: firebase.LoginOptions = { - type: LoginType.EMAIL_LINK, + type: firebase.LoginType.EMAIL_LINK, emailLinkOptions: { email: email, url: actionCodeSettings.url, @@ -140,12 +139,12 @@ export namespace auth { return this.loginHelper(signInWithEmailOption); } - public createUserWithEmailAndPassword(email: string, password: string): Promise { + public createUserWithEmailAndPassword(email: string, password: string): Promise { return new Promise((resolve, reject) => { firebase.createUser({ email: email, password: password - }).then((user: User) => { + }).then((user: firebase.User) => { this.currentUser = user; resolve(user); }).catch(err => reject(err)); diff --git a/src/app/database/index.ts b/src/app/database/index.ts index 892e431c..fb753174 100644 --- a/src/app/database/index.ts +++ b/src/app/database/index.ts @@ -1,5 +1,4 @@ -import * as firebase from "../../firebase"; -import { AddEventListenerResult, FBData } from "../../firebase"; +import { firebase } from "../../firebase"; import { nextPushId } from "./util/NextPushId"; export module database { @@ -42,7 +41,7 @@ export module database { }; firebase.addValueEventListener(onValueEvent, this.path).then( - (result: AddEventListenerResult) => { + (result: firebase.AddEventListenerResult) => { if (!Query.registeredListeners.has(this.path)) { Query.registeredListeners.set(this.path, []); } @@ -85,7 +84,7 @@ export module database { }); } - private getOnValueEventHandler(): (data: FBData) => void { + private getOnValueEventHandler(): (data: firebase.FBData) => void { return result => { const callbacks = Query.registeredCallbacks.get(this.path); callbacks && callbacks.map(callback => { diff --git a/src/app/firestore/index.ts b/src/app/firestore/index.ts index 1737a103..2f3de4a5 100644 --- a/src/app/firestore/index.ts +++ b/src/app/firestore/index.ts @@ -1,18 +1,18 @@ -import * as firebase from "../../firebase"; +import { firestore as fStore } from "../../firebase"; // import * as firebaseSdk from 'firebase/app'; export namespace firestore { export class Firestore /*implements firebaseSdk.firestore.Firestore*/ { - collection(collectionPath: string): firebase.firestore.CollectionReference { - return firebase.firestore.collection(collectionPath); + collection(collectionPath: string): fStore.CollectionReference { + return fStore.collection(collectionPath); } - collectionGroup(id: string): firebase.firestore.CollectionGroup { - return firebase.firestore.collectionGroup(id); + collectionGroup(id: string): fStore.CollectionGroup { + return fStore.collectionGroup(id); } - doc(path: string): firebase.firestore.DocumentReference { - return firebase.firestore.docRef(path); + doc(path: string): fStore.DocumentReference { + return fStore.docRef(path); } FieldValue(): firebase.firestore.FieldValue { @@ -21,30 +21,30 @@ export namespace firestore { value: undefined, serverTimestamp: () => "SERVER_TIMESTAMP", delete: () => "DELETE_FIELD", - arrayUnion: (...elements: any[]) => new firebase.firestore.FieldValue("ARRAY_UNION", elements), - arrayRemove: (...elements: any[]) => new firebase.firestore.FieldValue("ARRAY_REMOVE", elements), - increment: (n: number) => new firebase.firestore.FieldValue("INCREMENT", n) + arrayUnion: (...elements: any[]) => new fStore.FieldValue("ARRAY_UNION", elements), + arrayRemove: (...elements: any[]) => new fStore.FieldValue("ARRAY_REMOVE", elements), + increment: (n: number) => new fStore.FieldValue("INCREMENT", n) }; } - GeoPoint(latitude: number, longitude: number): firebase.firestore.GeoPoint { - return firebase.firestore.GeoPoint(latitude, longitude); + GeoPoint(latitude: number, longitude: number): fStore.GeoPoint { + return fStore.GeoPoint(latitude, longitude); } - runTransaction(updateFunction: (transaction: firebase.firestore.Transaction) => Promise): Promise { - return firebase.firestore.runTransaction(updateFunction); + runTransaction(updateFunction: (transaction: fStore.Transaction) => Promise): Promise { + return fStore.runTransaction(updateFunction); } - batch(): firebase.firestore.WriteBatch { - return firebase.firestore.batch(); + batch(): fStore.WriteBatch { + return fStore.batch(); } - settings(settings: firebase.firestore.Settings): void { - firebase.firestore.settings(settings); + settings(settings: fStore.Settings): void { + fStore.settings(settings); } clearPersistence(): Promise { - return firebase.firestore.clearPersistence(); + return fStore.clearPersistence(); } } } diff --git a/src/app/functions/index.ts b/src/app/functions/index.ts index 842fcffa..74f0ebe0 100644 --- a/src/app/functions/index.ts +++ b/src/app/functions/index.ts @@ -1,10 +1,10 @@ -import * as firebase from "../../firebase"; +import { functions as fNamepspace } from "../../firebase"; export namespace functions { // tslint:disable-next-line:class-name export class Functions { - httpsCallable(functionName: string, region?: firebase.functions.SupportedRegions) { - return firebase.functions.httpsCallable(functionName, region); + httpsCallable(functionName: string, region?: fNamepspace.SupportedRegions) { + return fNamepspace.httpsCallable(functionName, region); } } } \ No newline at end of file diff --git a/src/app/index.ts b/src/app/index.ts index 472b87b9..ee77ed5d 100644 --- a/src/app/index.ts +++ b/src/app/index.ts @@ -3,7 +3,7 @@ * Use 'const firebase = require("nativescript-plugin-firebase/app")' */ -import * as firebase from "../firebase"; +import { firebase } from "../firebase"; import { auth as firebaseAuthModule } from "./auth"; import { database as firebaseDatabaseModule } from "./database"; import { firestore as firebaseFirestoreModule } from "./firestore"; diff --git a/src/app/storage/index.ts b/src/app/storage/index.ts index d06af2f2..abf7d0cc 100644 --- a/src/app/storage/index.ts +++ b/src/app/storage/index.ts @@ -1,4 +1,4 @@ -import { File } from "tns-core-modules/file-system" +import { File } from "@nativescript/core"; import * as firebaseStorage from "../../storage/storage"; import { ListResult, UploadFileResult, UploadMetadata } from "../../storage/storage"; @@ -19,10 +19,11 @@ export module storage { parent: Reference | null; // TODO set this every time we navigate.. root: Reference; - fullPath = this.path; + fullPath: string; constructor(path?: string) { this.path = path; + this.fullPath = this.path; if (path && path.length > 0) { this.root = new Reference(); } else { diff --git a/src/firebase-common.ts b/src/firebase-common.ts index 8de6b907..96f3e708 100755 --- a/src/firebase-common.ts +++ b/src/firebase-common.ts @@ -1,6 +1,5 @@ -import { prompt } from "tns-core-modules/ui/dialogs"; -import { getString, setString } from "tns-core-modules/application-settings"; -import { firestore } from "./firebase"; +import { prompt, ApplicationSettings } from "@nativescript/core"; +import { firestore as fsNamespace } from "./firebase"; import * as admob from "./admob/admob"; import * as analytics from "./analytics/analytics"; import * as crashlytics from "./crashlytics/crashlytics"; @@ -10,7 +9,7 @@ import * as mlkit from "./mlkit"; // note that this implementation is overridden for iOS export class FieldValue { - constructor(public type: firestore.FieldValueType, + constructor(public type: fsNamespace.FieldValueType, public value: any) { } @@ -18,7 +17,7 @@ export class FieldValue { static delete = () => "DELETE_FIELD"; static arrayUnion = (...elements: any[]) => new FieldValue("ARRAY_UNION", elements); static arrayRemove = (...elements: any[]) => new FieldValue("ARRAY_REMOVE", elements); - static increment = (n: number) => new firebase.firestore.FieldValue("INCREMENT", n); + static increment = (n: number) => new FieldValue("INCREMENT", n); } export class GeoPoint { @@ -119,10 +118,10 @@ export const firebase: any = { }); }, rememberEmailForEmailLinkLogin: (email: string) => { - setString("FirebasePlugin.EmailLinkLogin", email); + ApplicationSettings.setString("FirebasePlugin.EmailLinkLogin", email); }, getRememberedEmailForEmailLinkLogin: () => { - return getString("FirebasePlugin.EmailLinkLogin"); + return ApplicationSettings.getString("FirebasePlugin.EmailLinkLogin"); }, strongTypeify: value => { if (value === "true") { @@ -215,18 +214,19 @@ export const firebase: any = { return result; } }; +export const firestore = firebase.firestore; -export abstract class DocumentSnapshot implements firestore.DocumentSnapshot { - public data: () => firestore.DocumentData; +export abstract class DocumentSnapshot { + public data: () => firebase.firestore.DocumentData; constructor(public id: string, public exists: boolean, - documentData: firestore.DocumentData, - public ref: firestore.DocumentReference) { + documentData: firebase.firestore.DocumentData, + public ref: firebase.firestore.DocumentReference) { this.data = () => exists ? documentData : undefined; } } -export function isDocumentReference(object: any): object is firestore.DocumentReference { +export function isDocumentReference(object: any): object is firebase.firestore.DocumentReference { return object && object.discriminator === "docRef"; } diff --git a/src/firebase.android.ts b/src/firebase.android.ts index c9a2d5d1..cc352ba0 100755 --- a/src/firebase.android.ts +++ b/src/firebase.android.ts @@ -1,12 +1,205 @@ -import * as appModule from "tns-core-modules/application"; -import { AndroidActivityResultEventData } from "tns-core-modules/application"; -import lazy from "tns-core-modules/utils/lazy"; -import { ad as AndroidUtils } from "tns-core-modules/utils/utils"; -import { ActionCodeSettings, DataSnapshot, FBDataSingleEvent, FBErrorData, firestore, GetAuthTokenOptions, IdTokenResult, OnDisconnect as OnDisconnectBase, QueryOptions, User } from "./firebase"; +import { Application, AndroidActivityResultEventData, 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"; +import { firestore } from "./firebase"; +export enum QueryOrderByType { + KEY, + VALUE, + CHILD, + PRIORITY +} + +/** + * The allowed values for QueryOptions.range.type. + */ +export enum QueryRangeType { + START_AT, + END_AT, + EQUAL_TO +} + +/** + * The allowed values for QueryOptions.limit.type. + */ +export enum QueryLimitType { + FIRST, + LAST +} +type ActionCodeSettings = { + url: string; + handleCodeInApp?: boolean; + android?: { + installApp?: boolean; + minimumVersion?: string; + packageName: string; + }; + iOS?: { + bundleId: string; + dynamicLinkDomain?: string; + }; +}; +export interface OnDisconnectBase { + cancel(): Promise; + + remove(): Promise; + + set(value: any): Promise; + + setWithPriority( + value: any, + priority: number | string + ): Promise; + + update(values: Object): Promise; +} + + +export interface DataSnapshot { + key: string; + ref: any; // TODO: Type it so that it returns a databaseReference. + child(path: string): DataSnapshot; + + exists(): boolean; + + forEach(action: (snapshot: DataSnapshot) => any): boolean; + + getPriority(): string | number | null; + + hasChild(path: string): boolean; + + hasChildren(): boolean; + + numChildren(): number; + + toJSON(): Object; + + val(): any; +} + +export interface FBData { + type: string; + key: string; + value: any; +} + +export interface FBDataSingleEvent extends FBData { + children?: Array; +} + +export interface FBErrorData { + error: string; +} + +export interface GetAuthTokenOptions { + /** + * Default false. + */ + forceRefresh?: boolean; +} +export interface IdTokenResult { + token: string; + claims: { [key: string]: any; }; + signInProvider: string; + expirationTime: number; + issuedAtTime: number; + authTime: number; +} +export interface QueryRangeOption { + type: QueryRangeType; + value: any; +} + +/** + * The options object passed into the query function. + */ +export interface QueryOptions { + /** + * How you'd like to sort the query result. + */ + orderBy: { + type: QueryOrderByType; + /** + * mandatory when type is QueryOrderByType.CHILD + */ + value?: string; + }; + + /** + * You can further restrict the returned results by specifying restrictions. + * Need more than one range restriction? Use 'ranges' instead. + */ + range?: QueryRangeOption; + + /** + * Same as 'range', but for a 'chain of ranges'. + * You can further restrict the returned results by specifying restrictions. + */ + ranges?: QueryRangeOption[]; + + /** + * You can limit the number of returned rows if you want to. + */ + limit?: { + type: QueryLimitType; + value: number; + }; + + /** + * Set this to true if you don't want to listen for any future updates, + * but just want to retrieve the current value. + * You can also use this to check if certain data is in the database. + * Default false. + */ + singleEvent?: boolean; +} +export interface Provider { + id: string; + token?: string; +} + +export interface User { + uid: string; + email?: string; + emailVerified: boolean; + displayName?: string; + phoneNumber?: string; + anonymous: boolean; + isAnonymous: boolean; // This is used by the web API + providers: Array; + photoURL?: string; + metadata: UserMetadata; + additionalUserInfo?: AdditionalUserInfo; + + /** iOS only */ + refreshToken?: string; + + getIdToken(forceRefresh?: boolean): Promise; + + getIdTokenResult(forceRefresh?: boolean): Promise; + + sendEmailVerification(actionCodeSettings?: ActionCodeSettings): Promise; +} + +/** + * The metadata of the user + */ +export interface UserMetadata { + creationTimestamp: Date; + lastSignInTimestamp: Date; +} + +/** + * Contains additional user information + */ +export interface AdditionalUserInfo { + profile: Map; + providerId: string; + username: string; + isNewUser: boolean; +} declare const com: any; const gmsAds = (com.google.android.gms).ads; const gmsTasks = (com.google.android.gms).tasks; @@ -44,7 +237,7 @@ const dynamicLinksEnabled = lazy(() => typeof (com.google.firebase.dynamiclinks) (() => { // note that this means we need to 'require()' the plugin before the app is loaded - appModule.on(appModule.launchEvent, args => { + Application.on(Application.launchEvent, args => { if (messagingEnabled()) { firebaseMessaging.onAppModuleLaunchEvent(args); } @@ -104,7 +297,7 @@ const dynamicLinksEnabled = lazy(() => typeof (com.google.firebase.dynamiclinks) } }); - appModule.on(appModule.resumeEvent, args => { + Application.on(Application.resumeEvent, args => { if (messagingEnabled()) { firebaseMessaging.onAppModuleResumeEvent(args); } @@ -191,7 +384,7 @@ firebase.toValue = val => { } else if (val instanceof GeoPoint) { returnVal = new com.google.firebase.firestore.GeoPoint(val.latitude, val.longitude); } else if (isDocumentReference(val)) { - returnVal = val.android; + returnVal = (val).android; } else { switch (typeof val) { case 'object': @@ -302,7 +495,7 @@ firebase.init = arg => { if (typeof (com.google.firebase.analytics) !== "undefined" && typeof (com.google.firebase.analytics.FirebaseAnalytics) !== "undefined") { com.google.firebase.analytics.FirebaseAnalytics.getInstance( - appModule.android.context || appModule.getNativeApplication() + Application.android.context || Application.getNativeApplication() ).setAnalyticsCollectionEnabled(arg.analyticsCollectionEnabled !== false); } @@ -377,18 +570,18 @@ firebase.init = arg => { // Firebase AdMob if (typeof (gmsAds) !== "undefined" && typeof (gmsAds.MobileAds) !== "undefined") { // init admob - gmsAds.MobileAds.initialize(appModule.android.context); + gmsAds.MobileAds.initialize(Application.android.context); } resolve(firebase.instance); }; try { - if (appModule.android.startActivity) { + if (Application.android.startActivity) { runInit(); } else { // if this is called before application.start() wait for the event to fire - appModule.on(appModule.launchEvent, runInit); + Application.on(Application.launchEvent, runInit); } } catch (ex) { console.log("Error in firebase.init: " + ex); @@ -471,7 +664,7 @@ firebase.getRemoteConfigDefaults = properties => { }; firebase._isGooglePlayServicesAvailable = () => { - const ctx = appModule.android.foregroundActivity || appModule.android.startActivity || appModule.getNativeApplication(); + const ctx = Application.android.foregroundActivity || Application.android.startActivity || Application.getNativeApplication(); const googleApiAvailability = com.google.android.gms.common.GoogleApiAvailability.getInstance(); const playServiceStatusSuccess = 0; // com.google.android.gms.common.ConnectionResult.SUCCESS; const playServicesStatus = googleApiAvailability.isGooglePlayServicesAvailable(ctx); @@ -589,15 +782,15 @@ firebase.getRemoteConfig = arg => { }; try { - if (appModule.android.foregroundActivity) { + if (Application.android.foregroundActivity) { runGetRemoteConfig(); } else { // if this is called before application.start(), wait for the event to fire const callback = () => { runGetRemoteConfig(); - appModule.off(appModule.resumeEvent, callback); + Application.off(Application.resumeEvent, callback); }; - appModule.on(appModule.resumeEvent, callback); + Application.on(Application.resumeEvent, callback); } } catch (ex) { console.log("Error in firebase.getRemoteConfig: " + ex); @@ -827,8 +1020,8 @@ firebase.login = arg => { return new Promise((resolve, reject) => { try { // need these to support using phone auth more than once - this.resolve = resolve; - this.reject = reject; + firebase.resolve = resolve; + firebase.reject = reject; if (!firebase._isGooglePlayServicesAvailable()) { reject("Google Play services is required for this feature, but not available on this device"); @@ -846,11 +1039,15 @@ firebase.login = arg => { if (firebase._mGoogleApiClient) { com.google.android.gms.auth.api.Auth.GoogleSignInApi.revokeAccess(firebase._mGoogleApiClient); } - this.reject("Logging in the user failed. " + (task.getException() && task.getException().getReason ? task.getException().getReason() : task.getException())); + 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(); - this.resolve(toLoginResult(user, additionalUserInfo)); + if (firebase.resolve) { + firebase.resolve(toLoginResult(user, additionalUserInfo)); + } } } }); @@ -891,9 +1088,9 @@ firebase.login = arg => { // URL you want to redirect back to. The domain must be whitelisted in the Firebase Console. .setUrl(arg.emailLinkOptions.url) .setHandleCodeInApp(true) - .setIOSBundleId(arg.emailLinkOptions.iOS ? arg.emailLinkOptions.iOS.bundleId : appModule.android.context.getPackageName()) + .setIOSBundleId(arg.emailLinkOptions.iOS ? arg.emailLinkOptions.iOS.bundleId : Application.android.context.getPackageName()) .setAndroidPackageName( - arg.emailLinkOptions.android ? arg.emailLinkOptions.android.packageName : appModule.android.context.getPackageName(), + 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") .build(); @@ -944,9 +1141,13 @@ firebase.login = arg => { firebase._verifyPhoneNumberInProgress = false; const errorMessage = firebaseException.getMessage(); if (errorMessage.includes("INVALID_APP_CREDENTIAL")) { - this.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"); + 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 { - this.reject(errorMessage); + if (firebase.reject) { + firebase.reject(errorMessage); + } } }, onCodeSent: (verificationId, forceResendingToken) => { @@ -956,8 +1157,8 @@ firebase.login = arg => { if (firebase._verifyPhoneNumberInProgress) { firebase._verifyPhoneNumberInProgress = false; firebase.requestPhoneAuthVerificationCode(userResponse => { - if (userResponse === undefined && this.reject) { - this.reject("Prompt was canceled"); + if (userResponse === undefined && firebase.reject) { + firebase.reject("Prompt was canceled"); return; } const authCredential = com.google.firebase.auth.PhoneAuthProvider.getCredential(verificationId, userResponse); @@ -981,7 +1182,7 @@ firebase.login = arg => { arg.phoneOptions.phoneNumber, timeout, // timeout (in seconds, because of the next argument) java.util.concurrent.TimeUnit.SECONDS, - appModule.android.foregroundActivity, + Application.android.foregroundActivity, new OnVerificationStateChangedCallbacks()); } else if (arg.type === firebase.LoginType.CUSTOM) { @@ -1012,15 +1213,15 @@ firebase.login = arg => { // Lazy loading the Facebook callback manager if (!fbCallbackManager) { - com.facebook.FacebookSdk.sdkInitialize(appModule.getNativeApplication()); + com.facebook.FacebookSdk.sdkInitialize(Application.getNativeApplication()); fbCallbackManager = com.facebook.CallbackManager.Factory.create(); } const callback = (eventData: AndroidActivityResultEventData) => { - appModule.android.off(appModule.AndroidApplication.activityResultEvent, callback); + Application.android.off(AndroidApplication.activityResultEvent, callback); fbCallbackManager.onActivityResult(eventData.requestCode, eventData.resultCode, eventData.intent); }; - appModule.android.on(appModule.AndroidApplication.activityResultEvent, callback); + Application.android.on(AndroidApplication.activityResultEvent, callback); const fbLoginManager = com.facebook.login.LoginManager.getInstance(); fbLoginManager.registerCallback( @@ -1050,9 +1251,9 @@ firebase.login = arg => { if (arg.facebookOptions && arg.facebookOptions.scopes) { scopes = arg.facebookOptions.scopes; } - const permissions = AndroidUtils.collections.stringArrayToStringSet(scopes); + const permissions = Utils.android.collections.stringArrayToStringSet(scopes); - const activity = appModule.android.foregroundActivity; + const activity = Application.android.foregroundActivity; fbLoginManager.logInWithReadPermissions(activity, permissions); } else if (arg.type === firebase.LoginType.APPLE) { @@ -1097,7 +1298,7 @@ firebase.login = arg => { const provider = oAuthProviderBuilder.build(); - firebaseAuth.startActivityForSignInWithProvider(appModule.android.foregroundActivity || appModule.android.startActivity, provider) + firebaseAuth.startActivityForSignInWithProvider(Application.android.foregroundActivity || Application.android.startActivity, provider) .addOnSuccessListener(onSuccessListener) .addOnFailureListener(onFailureListener); } @@ -1108,8 +1309,8 @@ firebase.login = arg => { return; } - const clientStringId = AndroidUtils.resources.getStringId("default_web_client_id"); - const clientId = AndroidUtils.getApplicationContext().getResources().getString(clientStringId); + const clientStringId = Utils.android.resources.getStringId("default_web_client_id"); + const clientId = Utils.android.getApplicationContext().getResources().getString(clientStringId); // Configure Google Sign In const googleSignInOptionsBuilder = new com.google.android.gms.auth.api.signin.GoogleSignInOptions.Builder(com.google.android.gms.auth.api.signin.GoogleSignInOptions.DEFAULT_SIGN_IN) @@ -1136,17 +1337,17 @@ firebase.login = arg => { } }); - firebase._mGoogleApiClient = new com.google.android.gms.common.api.GoogleApiClient.Builder(appModule.getNativeApplication()) + firebase._mGoogleApiClient = new com.google.android.gms.common.api.GoogleApiClient.Builder(Application.getNativeApplication()) .addOnConnectionFailedListener(onConnectionFailedListener) .addApi(com.google.android.gms.auth.api.Auth.GOOGLE_SIGN_IN_API, googleSignInOptions) .build(); const signInIntent = com.google.android.gms.auth.api.Auth.GoogleSignInApi.getSignInIntent(firebase._mGoogleApiClient); - (appModule.android.foregroundActivity || appModule.android.startActivity).startActivityForResult(signInIntent, GOOGLE_SIGNIN_INTENT_ID); + (Application.android.foregroundActivity || Application.android.startActivity).startActivityForResult(signInIntent, GOOGLE_SIGNIN_INTENT_ID); const callback = (eventData: AndroidActivityResultEventData) => { if (eventData.requestCode === GOOGLE_SIGNIN_INTENT_ID) { - appModule.android.off(appModule.AndroidApplication.activityResultEvent, callback); + Application.android.off(AndroidApplication.activityResultEvent, callback); const googleSignInResult = com.google.android.gms.auth.api.Auth.GoogleSignInApi.getSignInResultFromIntent(eventData.intent); if (googleSignInResult === null) { reject("No googleSignInResult, eventData.intent seems to be invalid"); @@ -1178,7 +1379,7 @@ firebase.login = arg => { } } }; - appModule.android.on(appModule.AndroidApplication.activityResultEvent, callback); + Application.android.on(AndroidApplication.activityResultEvent, callback); } else { reject("Unsupported auth type: " + arg.type); @@ -2026,26 +2227,26 @@ const ensureFirestore = (): void => { } }; -class FirestoreWriteBatch implements firestore.WriteBatch { +class FirestoreWriteBatch { public nativeWriteBatch: com.google.firebase.firestore.WriteBatch; - public set = (documentRef: firestore.DocumentReference, data: firestore.DocumentData, options?: firestore.SetOptions): firestore.WriteBatch => { + public set = (documentRef: firestore.DocumentReference, data: firestore.DocumentData, options?: firestore.SetOptions): any => { if (options && options.merge) { - this.nativeWriteBatch.set(documentRef.android, firebase.toValue(data), com.google.firebase.firestore.SetOptions.merge()); + this.nativeWriteBatch.set((documentRef).android, firebase.toValue(data), com.google.firebase.firestore.SetOptions.merge()); } else { - this.nativeWriteBatch.set(documentRef.android, firebase.toValue(data)); + this.nativeWriteBatch.set((documentRef).android, firebase.toValue(data)); } return this; } - public update = (documentRef: firestore.DocumentReference, data: firestore.UpdateData): firestore.WriteBatch => { - this.nativeWriteBatch.update(documentRef.android, firebase.toValue(data)); + public update(documentRef: firestore.DocumentReference, data: firestore.UpdateData): any { + this.nativeWriteBatch.update((documentRef).android, firebase.toValue(data)); return this; } - public delete = (documentRef: firestore.DocumentReference): firestore.WriteBatch => { - this.nativeWriteBatch.delete(documentRef.android); + public delete = (documentRef: firestore.DocumentReference): any => { + this.nativeWriteBatch.delete((documentRef).android); return this; } @@ -2066,7 +2267,7 @@ class FirestoreWriteBatch implements firestore.WriteBatch { } } -firebase.firestore.batch = (): firestore.WriteBatch => { +firebase.firestore.batch = (): any => { const batch = new FirestoreWriteBatch(); batch.nativeWriteBatch = com.google.firebase.firestore.FirebaseFirestore.getInstance().batch(); return batch; @@ -2090,26 +2291,26 @@ class FirestoreTransaction implements firestore.Transaction { public nativeTransaction: com.google.firebase.firestore.Transaction; public get = (documentRef: firestore.DocumentReference): DocumentSnapshot => { - const docSnapshot: com.google.firebase.firestore.DocumentSnapshot = this.nativeTransaction.get(documentRef.android); + const docSnapshot: com.google.firebase.firestore.DocumentSnapshot = this.nativeTransaction.get((documentRef).android); return new DocumentSnapshot(docSnapshot ? docSnapshot.getId() : null, docSnapshot.exists(), firebase.toJsObject(docSnapshot.getData())); }; public set = (documentRef: firestore.DocumentReference, data: firestore.DocumentData, options?: firestore.SetOptions): firestore.Transaction => { if (options && options.merge) { - this.nativeTransaction.set(documentRef.android, firebase.toValue(data), com.google.firebase.firestore.SetOptions.merge()); + this.nativeTransaction.set((documentRef).android, firebase.toValue(data), com.google.firebase.firestore.SetOptions.merge()); } else { - this.nativeTransaction.set(documentRef.android, firebase.toValue(data)); + this.nativeTransaction.set((documentRef).android, firebase.toValue(data)); } return this; }; public update = (documentRef: firestore.DocumentReference, data: firestore.UpdateData): firestore.Transaction => { - this.nativeTransaction.update(documentRef.android, firebase.toValue(data)); + this.nativeTransaction.update((documentRef).android, firebase.toValue(data)); return this; }; public delete = (documentRef: firestore.DocumentReference): firestore.Transaction => { - this.nativeTransaction.delete(documentRef.android); + this.nativeTransaction.delete((documentRef).android); return this; } }; @@ -2157,7 +2358,7 @@ firebase.firestore.settings = (settings: firestore.Settings) => { if (typeof (com.google.firebase.firestore) !== "undefined") { try { const builder = new com.google.firebase.firestore.FirebaseFirestoreSettings.Builder(); - (settings.cacheSizeBytes !== undefined) && builder.setCacheSizeBytes(long(settings.cacheSizeBytes)); + ((settings).cacheSizeBytes !== undefined) && builder.setCacheSizeBytes(long((settings).cacheSizeBytes)); (settings.ssl !== undefined) && builder.setSslEnabled(settings.ssl); (settings.host !== undefined) && builder.setHost(settings.host); (initializeArguments.persist !== undefined) && builder.setPersistenceEnabled(initializeArguments.persist); @@ -2203,7 +2404,7 @@ firebase.firestore.collection = (collectionPath: string): firestore.CollectionRe } }; -firebase.firestore.collectionGroup = (id: string): firestore.CollectionGroup => { +firebase.firestore.collectionGroup = (id: string): any => { ensureFirestore(); try { const db = com.google.firebase.firestore.FirebaseFirestore.getInstance(); @@ -2294,7 +2495,7 @@ firebase.firestore._getDocumentReference = (docRef?: JDocumentReference): firest get: (options?: firestore.GetOptions) => firebase.firestore.getDocument(collectionPath, docRef.getId(), options), update: (data: any) => firebase.firestore.update(collectionPath, docRef.getId(), data), delete: () => firebase.firestore.delete(collectionPath, docRef.getId()), - onSnapshot: (optionsOrCallback: firestore.SnapshotListenOptions | ((snapshot: DocumentSnapshot) => void), callbackOrOnError?: (docOrError: DocumentSnapshot | Error) => void, onError?: (error: Error) => void) => firebase.firestore.onDocumentSnapshot(docRef, optionsOrCallback, callbackOrOnError, onError), + onSnapshot: (optionsOrCallback: firestore.SnapshotListenOptions | ((snapshot: firestore.DocumentSnapshot) => void), callbackOrOnError?: (docOrError: firestore.DocumentSnapshot | Error) => void, onError?: (error: Error) => void) => firebase.firestore.onDocumentSnapshot(docRef, optionsOrCallback, callbackOrOnError, onError), android: docRef }; }; @@ -2529,7 +2730,7 @@ firebase.firestore.getDocument = (collectionPath: string, documentPath: string, reject(ex && ex.getReason ? ex.getReason() : ex); } else { const result: com.google.firebase.firestore.DocumentSnapshot = task.getResult(); - resolve(new DocumentSnapshot(result)); + resolve(new DocumentSnapshot(result)); } } }); @@ -2559,7 +2760,7 @@ firebase.firestore._getQuery = (collectionPath: string, query: com.google.fireba return { get: () => new Promise((resolve, reject) => { const onCompleteListener = new gmsTasks.OnCompleteListener({ - onComplete: task => { + onComplete: (task: any) => { if (!task.isSuccessful()) { const ex = task.getException(); reject(ex && ex.getReason ? ex.getReason() : ex); @@ -2674,7 +2875,7 @@ function convertDocChangeType(type: com.google.firebase.firestore.DocumentChange } function convertDocument(qDoc: com.google.firebase.firestore.QueryDocumentSnapshot): firestore.QueryDocumentSnapshot { - return new DocumentSnapshot(qDoc); + return new DocumentSnapshot(qDoc); } export class QuerySnapshot implements firestore.QuerySnapshot { @@ -2693,7 +2894,7 @@ export class QuerySnapshot implements firestore.QuerySnapshot { const docSnapshots: firestore.QueryDocumentSnapshot[] = []; for (let i = 0; i < this.snapshot.size(); i++) { const documentSnapshot: com.google.firebase.firestore.DocumentSnapshot = this.snapshot.getDocuments().get(i); - docSnapshots.push(new DocumentSnapshot(documentSnapshot)); + docSnapshots.push(new DocumentSnapshot(documentSnapshot)); } this._docSnapshots = docSnapshots; @@ -2733,4 +2934,4 @@ export class QuerySnapshot implements firestore.QuerySnapshot { } } -module.exports = firebase; +export * from './firebase-common'; diff --git a/src/firebase.d.ts b/src/firebase.d.ts index f6ab17b9..bf21627c 100644 --- a/src/firebase.d.ts +++ b/src/firebase.d.ts @@ -1,683 +1,803 @@ -/** - * The allowed values for LoginOptions.type. - */ -export enum LoginType { +export namespace firebase { /** - * No further data is required. + * The allowed values for LoginOptions.type. */ - ANONYMOUS, - /** - * This requires you to pass in the 'passwordOptions' as well. - */ - PASSWORD, - /** - * This requires you to add the 'phoneOptions' as well. - */ - PHONE, - /** - * This requires you to pass either an authentication token generated by your backend server - * or the tokenProviderFn function that returns a promise to provide the token (see 'customOptions'). - * See: https://firebase.google.com/docs/auth/server - */ - CUSTOM, - /** - * This requires you to setup Facebook Auth in the Firebase console, - * as well as uncommenting the SDK includes in include.gradle (Android) and Podfile (iOS). - * You can pass in an optional 'facebookOptions' object to override the default scopes. - */ - FACEBOOK, + export enum LoginType { + /** + * No further data is required. + */ + ANONYMOUS, + /** + * This requires you to pass in the 'passwordOptions' as well. + */ + PASSWORD, + /** + * This requires you to add the 'phoneOptions' as well. + */ + PHONE, + /** + * This requires you to pass either an authentication token generated by your backend server + * or the tokenProviderFn function that returns a promise to provide the token (see 'customOptions'). + * See: https://firebase.google.com/docs/auth/server + */ + CUSTOM, + /** + * This requires you to setup Facebook Auth in the Firebase console, + * as well as uncommenting the SDK includes in include.gradle (Android) and Podfile (iOS). + * You can pass in an optional 'facebookOptions' object to override the default scopes. + */ + FACEBOOK, + /** + * This requires you to setup Google Sign In in the Firebase console, + * as well as uncommenting the SDK includes in include.gradle (Android) and Podfile (iOS). + * You can pass in an optional 'googleOptions' object to set a 'hostedDomain'. + */ + GOOGLE, + /** + * This requires you to pass in the 'emailLinkOptions' as well. + * Note that 'Firebase Dynamic Links' must be enabled for this login type to work. + */ + EMAIL_LINK, + /** + * Apple + */ + APPLE, + } + + export enum LogComplexEventTypeParameter { + STRING, + INT, + FLOAT, + DOUBLE, + LONG, + ARRAY, + BOOLEAN, + } + /** - * This requires you to setup Google Sign In in the Firebase console, - * as well as uncommenting the SDK includes in include.gradle (Android) and Podfile (iOS). - * You can pass in an optional 'googleOptions' object to set a 'hostedDomain'. + * The allowed values for QueryOptions.orderBy.type. */ - GOOGLE, + export enum QueryOrderByType { + KEY, + VALUE, + CHILD, + PRIORITY, + } + /** - * This requires you to pass in the 'emailLinkOptions' as well. - * Note that 'Firebase Dynamic Links' must be enabled for this login type to work. + * The allowed values for QueryOptions.range.type. */ - EMAIL_LINK, + export enum QueryRangeType { + START_AT, + END_AT, + EQUAL_TO, + } + /** - * Apple + * The allowed values for QueryOptions.limit.type. */ - APPLE -} + export enum QueryLimitType { + FIRST, + LAST, + } -export enum LogComplexEventTypeParameter { - STRING, - INT, - FLOAT, - DOUBLE, - LONG, - ARRAY, - BOOLEAN -} + export enum ServerValue { + /** + * When for instance using setValue you can set a timestamp property to this placeholder value. + * Example: + * updateTs: firebase.ServerValue.TIMESTAMP + */ + TIMESTAMP, + } -/** - * The allowed values for QueryOptions.orderBy.type. - */ -export enum QueryOrderByType { - KEY, - VALUE, - CHILD, - PRIORITY -} + export interface MessagingOptions { + /** + * For Messaging, either pass in this callback function here, or use addOnMessageReceivedCallback. + */ + onPushTokenReceivedCallback?: (token: string) => void; -/** - * The allowed values for QueryOptions.range.type. - */ -export enum QueryRangeType { - START_AT, - END_AT, - EQUAL_TO -} + /** + * For Messaging, either pass in this callback function here, or use addOnPushTokenReceivedCallback. + */ + onMessageReceivedCallback?: (message: Message) => void; -/** - * The allowed values for QueryOptions.limit.type. - */ -export enum QueryLimitType { - FIRST, - LAST -} + /** + * For Messaging (Push Notifications). Whether you want this plugin to automatically display the notifications or just notify the callback. + * Currently used on iOS only. Default true. + */ + showNotifications?: boolean; -export enum ServerValue { - /** - * When for instance using setValue you can set a timestamp property to this placeholder value. - * Example: - * updateTs: firebase.ServerValue.TIMESTAMP - */ - TIMESTAMP -} + /** + * For Messaging (Push Notifications). Whether you want this plugin to always handle the notifications when the app is in foreground. + * Currently used on iOS only. Default false. + */ + showNotificationsWhenInForeground?: boolean; -export interface MessagingOptions { - /** - * For Messaging, either pass in this callback function here, or use addOnMessageReceivedCallback. - */ - onPushTokenReceivedCallback?: (token: string) => void; + /** + * Automatically clear the badges on starting. + * Currently used on iOS only. Default true. + */ + autoClearBadge?: boolean; + } /** - * For Messaging, either pass in this callback function here, or use addOnPushTokenReceivedCallback. + * The options object passed into the init function. */ - onMessageReceivedCallback?: (message: Message) => void; + export interface InitOptions extends MessagingOptions { + /** + * Allow the app to send analytics data to Firebase. + * Can also be set later with analytics.setAnalyticsCollectionEnabled. + * Default true. + */ + analyticsCollectionEnabled?: boolean; - /** - * For Messaging (Push Notifications). Whether you want this plugin to automatically display the notifications or just notify the callback. - * Currently used on iOS only. Default true. - */ - showNotifications?: boolean; + /** + * Allow the app to collect Crashlytics data and send it to Firebase. + * Can also be set later with crashlytics.setCrashReportingEnabled. + * Only useful in case it was disabled in AndroidManfifest.xml and/or Info.plist, + * see https://firebase.google.com/docs/crashlytics/customize-crash-reports + */ + crashlyticsCollectionEnabled?: boolean; - /** - * For Messaging (Push Notifications). Whether you want this plugin to always handle the notifications when the app is in foreground. - * Currently used on iOS only. Default false. - */ - showNotificationsWhenInForeground?: boolean; + /** + * Allow disk persistence. Default true for Firestore, false for regular Firebase DB. + */ + persist?: boolean; - /** - * Automatically clear the badges on starting. - * Currently used on iOS only. Default true. - */ - autoClearBadge?: boolean; -} + /** + * Get notified when the user is logged in. + */ + onAuthStateChanged?: (data: AuthStateData) => void; -/** - * The options object passed into the init function. - */ -export interface InitOptions extends MessagingOptions { - /** - * Allow the app to send analytics data to Firebase. - * Can also be set later with analytics.setAnalyticsCollectionEnabled. - * Default true. - */ - analyticsCollectionEnabled?: boolean; + /** + * Attempt to sign out before initializing, useful in case previous + * project token is cached which leads to following type of error: + * "[FirebaseDatabase] Authentication failed: invalid_token ..." + * Default false. + */ + iOSEmulatorFlush?: boolean; - /** - * Allow the app to collect Crashlytics data and send it to Firebase. - * Can also be set later with crashlytics.setCrashReportingEnabled. - * Only useful in case it was disabled in AndroidManfifest.xml and/or Info.plist, - * see https://firebase.google.com/docs/crashlytics/customize-crash-reports - */ - crashlyticsCollectionEnabled?: boolean; + /** + * For Firebase Storage you can pass in something like 'gs://n-plugin-test.appspot.com' + * here so we can cache it. Otherwise pass in the 'bucket' param when using Storage features. + * Can be found in the firebase console. + */ + storageBucket?: string; - /** - * Allow disk persistence. Default true for Firestore, false for regular Firebase DB. - */ - persist?: boolean; + /** + * Get notified when a dynamic link was used to launch the app. Alternatively use addOnDynamicLinkReceivedCallback. + * TODO iOS seems to return an object; not a string + */ + onDynamicLinkCallback?: (data: DynamicLinkData) => void; + } - /** - * Get notified when the user is logged in. - */ - onAuthStateChanged?: (data: AuthStateData) => void; + export interface QueryRangeOption { + type: QueryRangeType; + value: any; + } /** - * Attempt to sign out before initializing, useful in case previous - * project token is cached which leads to following type of error: - * "[FirebaseDatabase] Authentication failed: invalid_token ..." - * Default false. + * The options object passed into the query function. */ - iOSEmulatorFlush?: boolean; + export interface QueryOptions { + /** + * How you'd like to sort the query result. + */ + orderBy: { + type: QueryOrderByType; + /** + * mandatory when type is QueryOrderByType.CHILD + */ + value?: string; + }; - /** - * For Firebase Storage you can pass in something like 'gs://n-plugin-test.appspot.com' - * here so we can cache it. Otherwise pass in the 'bucket' param when using Storage features. - * Can be found in the firebase console. - */ - storageBucket?: string; + /** + * You can further restrict the returned results by specifying restrictions. + * Need more than one range restriction? Use 'ranges' instead. + */ + range?: QueryRangeOption; - /** - * Get notified when a dynamic link was used to launch the app. Alternatively use addOnDynamicLinkReceivedCallback. - * TODO iOS seems to return an object; not a string - */ - onDynamicLinkCallback?: (data: DynamicLinkData) => void; -} + /** + * Same as 'range', but for a 'chain of ranges'. + * You can further restrict the returned results by specifying restrictions. + */ + ranges?: QueryRangeOption[]; -export interface QueryRangeOption { - type: QueryRangeType; - value: any; -} + /** + * You can limit the number of returned rows if you want to. + */ + limit?: { + type: QueryLimitType; + value: number; + }; -/** - * The options object passed into the query function. - */ -export interface QueryOptions { - /** - * How you'd like to sort the query result. - */ - orderBy: { - type: QueryOrderByType; /** - * mandatory when type is QueryOrderByType.CHILD + * Set this to true if you don't want to listen for any future updates, + * but just want to retrieve the current value. + * You can also use this to check if certain data is in the database. + * Default false. */ - value?: string; - }; + singleEvent?: boolean; + } - /** - * You can further restrict the returned results by specifying restrictions. - * Need more than one range restriction? Use 'ranges' instead. - */ - range?: QueryRangeOption; + export interface GetAuthTokenOptions { + /** + * Default false. + */ + forceRefresh?: boolean; + } - /** - * Same as 'range', but for a 'chain of ranges'. - * You can further restrict the returned results by specifying restrictions. - */ - ranges?: QueryRangeOption[]; + export interface IdTokenResult { + token: string; + claims: { [key: string]: any }; + signInProvider: string; + expirationTime: number; + issuedAtTime: number; + authTime: number; + } - /** - * You can limit the number of returned rows if you want to. - */ - limit?: { - type: QueryLimitType; - value: number; - }; + export interface Provider { + id: string; + token?: string; + } - /** - * Set this to true if you don't want to listen for any future updates, - * but just want to retrieve the current value. - * You can also use this to check if certain data is in the database. - * Default false. - */ - singleEvent?: boolean; -} + export interface FirebasePasswordLoginOptions { + email: string; + password: string; + } -export interface GetAuthTokenOptions { - /** - * Default false. - */ - forceRefresh?: boolean; -} + export interface FirebaseEmailLinkActionCodeSettings { + url: string; + iOS?: { + bundleId: string; + }; + android?: { + packageName: string; + installApp?: false; + minimumVersion?: string; + }; + } -export interface IdTokenResult { - token: string; - claims: { [key: string]: any; }; - signInProvider: string; - expirationTime: number; - issuedAtTime: number; - authTime: number; -} + export interface FirebaseEmailLinkLoginOptions + extends FirebaseEmailLinkActionCodeSettings { + email: string; + } -export interface Provider { - id: string; - token?: string; -} + export interface FirebasePhoneLoginOptions { + phoneNumber: string; + /** + * The message show to the user that prompts him to enter the received verification code. + * Default: "Verification code". + */ + verificationPrompt?: string; + android?: { + /** + * The maximum amount of time you are willing to wait for SMS auto-retrieval to be completed by the library. Maximum allowed value is 2 minutes. Use 0 to disable SMS-auto-retrieval. If you specified a positive value less than 30 seconds, library will default to 30 seconds. + * Default: 60 (seconds) + * See: https://firebase.google.com/docs/reference/android/com/google/firebase/auth/PhoneAuthProvider + */ + timeout: number; + }; + } -export interface FirebasePasswordLoginOptions { - email: string; - password: string; -} + export interface FirebaseGoogleLoginOptions { + hostedDomain?: string; + /** + * You can add scopes like "https://www.googleapis.com/auth/contacts.readonly" and "https://www.googleapis.com/auth/user.birthday.read" + * + * Default: ["profile", "email"] + */ + scopes?: Array; + } -export interface FirebaseEmailLinkActionCodeSettings { - url: string; - iOS?: { - bundleId: string; - }; - android?: { - packageName: string; - installApp?: false; - minimumVersion?: string; - }; -} + export interface FirebaseFacebookLoginOptions { + /** + * Default: ["public_profile", "email"] + */ + scopes?: Array; + } -export interface FirebaseEmailLinkLoginOptions extends FirebaseEmailLinkActionCodeSettings { - email: string; -} + export type AppleLoginScope = "name" | "email"; -export interface FirebasePhoneLoginOptions { - phoneNumber: string; - /** - * The message show to the user that prompts him to enter the received verification code. - * Default: "Verification code". - */ - verificationPrompt?: string; - android?: { + export interface AppleLoginOptions { /** - * The maximum amount of time you are willing to wait for SMS auto-retrieval to be completed by the library. Maximum allowed value is 2 minutes. Use 0 to disable SMS-auto-retrieval. If you specified a positive value less than 30 seconds, library will default to 30 seconds. - * Default: 60 (seconds) - * See: https://firebase.google.com/docs/reference/android/com/google/firebase/auth/PhoneAuthProvider + * Default: ["name", "email"] */ - timeout: number; - }; -} + scopes?: Array; + /** + * Android only. + * Supported locales: https://developer.apple.com/documentation/signinwithapplejs/incorporating_sign_in_with_apple_into_other_platforms#3332112 + * Default: "en". + */ + locale?: string; + } -export interface FirebaseGoogleLoginOptions { - hostedDomain?: string; - /** - * You can add scopes like "https://www.googleapis.com/auth/contacts.readonly" and "https://www.googleapis.com/auth/user.birthday.read" - * - * Default: ["profile", "email"] - */ - scopes?: Array; -} + export interface FirebaseCustomLoginOptions { + /** + * The JSON Web Token (JWT) to use for authentication. + * Either specify this, or 'tokenProviderFn'. + * See: https://firebase.google.com/docs/auth/server + */ + token?: string; + /** + * A function that returns a promise with the JSON Web Token (JWT) to use for authentication. + * Either specify this, or 'token'. + * See: https://firebase.google.com/docs/auth/server + */ + tokenProviderFn?: () => Promise; + } + + export interface LoginIOSOptions { + controller?: any; + } -export interface FirebaseFacebookLoginOptions { /** - * Default: ["public_profile", "email"] + * The options object passed into the login function. */ - scopes?: Array; -} + export interface LoginOptions { + type: LoginType; + passwordOptions?: FirebasePasswordLoginOptions; + emailLinkOptions?: FirebaseEmailLinkLoginOptions; + phoneOptions?: FirebasePhoneLoginOptions; + googleOptions?: FirebaseGoogleLoginOptions; + facebookOptions?: FirebaseFacebookLoginOptions; + appleOptions?: AppleLoginOptions; + customOptions?: FirebaseCustomLoginOptions; + ios?: LoginIOSOptions; -export type AppleLoginScope = "name" | "email"; + /** + * @deprecated Please use the 'passwordOptions?: FirebasePasswordLoginOptions' object instead. + */ + email?: string; + /** + * @deprecated Please use the 'passwordOptions?: FirebasePasswordLoginOptions' object instead. + */ + password?: string; + /** + * @deprecated Please use the 'customOptions?: FirebaseCustomLoginOptions' object instead. + */ + token?: string; + /** + * @deprecated Please use the 'customOptions?: FirebaseCustomLoginOptions' object instead. + */ + tokenProviderFn?: () => Promise; + /** + * @deprecated Please use the 'facebookOptions?: FirebaseFacebookLoginOptions' object instead. + */ + scope?: string[]; + } + + export interface ReauthenticateOptions { + type: LoginType; + passwordOptions?: FirebasePasswordLoginOptions; + /** + * @deprecated Please use the 'passwordOptions?: FirebasePasswordLoginOptions' object instead. + */ + email?: string; + /** + * @deprecated Please use the 'passwordOptions?: FirebasePasswordLoginOptions' object instead. + */ + password?: string; + } + + type ActionCodeSettings = { + url: string; + handleCodeInApp?: boolean; + android?: { + installApp?: boolean; + minimumVersion?: string; + packageName: string; + }; + iOS?: { + bundleId: string; + dynamicLinkDomain?: string; + }; + }; -export interface AppleLoginOptions { - /** - * Default: ["name", "email"] - */ - scopes?: Array; /** - * Android only. - * Supported locales: https://developer.apple.com/documentation/signinwithapplejs/incorporating_sign_in_with_apple_into_other_platforms#3332112 - * Default: "en". + * The returned object from the login function. */ - locale?: string; -} + export interface User { + uid: string; + email?: string; + emailVerified: boolean; + displayName?: string; + phoneNumber?: string; + anonymous: boolean; + isAnonymous: boolean; // This is used by the web API + providers: Array; + photoURL?: string; + metadata: UserMetadata; + additionalUserInfo?: AdditionalUserInfo; + + /** iOS only */ + refreshToken?: string; + + getIdToken(forceRefresh?: boolean): Promise; + + getIdTokenResult(forceRefresh?: boolean): Promise; + + sendEmailVerification( + actionCodeSettings?: ActionCodeSettings + ): Promise; + } -export interface FirebaseCustomLoginOptions { /** - * The JSON Web Token (JWT) to use for authentication. - * Either specify this, or 'tokenProviderFn'. - * See: https://firebase.google.com/docs/auth/server + * The metadata of the user */ - token?: string; + export interface UserMetadata { + creationTimestamp: Date; + lastSignInTimestamp: Date; + } + /** - * A function that returns a promise with the JSON Web Token (JWT) to use for authentication. - * Either specify this, or 'token'. - * See: https://firebase.google.com/docs/auth/server + * Contains additional user information */ - tokenProviderFn?: () => Promise; -} - -export interface LoginIOSOptions { - controller?: any; -} - -/** - * The options object passed into the login function. - */ -export interface LoginOptions { - type: LoginType; - passwordOptions?: FirebasePasswordLoginOptions; - emailLinkOptions?: FirebaseEmailLinkLoginOptions; - phoneOptions?: FirebasePhoneLoginOptions; - googleOptions?: FirebaseGoogleLoginOptions; - facebookOptions?: FirebaseFacebookLoginOptions; - appleOptions?: AppleLoginOptions; - customOptions?: FirebaseCustomLoginOptions; - ios?: LoginIOSOptions; + export interface AdditionalUserInfo { + profile: Map; + providerId: string; + username: string; + isNewUser: boolean; + } /** - * @deprecated Please use the 'passwordOptions?: FirebasePasswordLoginOptions' object instead. + * The returned object from the push function. */ - email?: string; + export interface PushResult { + key: string; + } + /** - * @deprecated Please use the 'passwordOptions?: FirebasePasswordLoginOptions' object instead. + * The returned object from the addEventListener functions. */ - password?: string; + export interface AddEventListenerResult { + path: string; + listeners: Array; + } + /** - * @deprecated Please use the 'customOptions?: FirebaseCustomLoginOptions' object instead. + * The options object passed into the createUser function. */ - token?: string; + export interface CreateUserOptions { + email: string; + password: string; + } + /** - * @deprecated Please use the 'customOptions?: FirebaseCustomLoginOptions' object instead. + * The options object passed into the updateProfile function. */ - tokenProviderFn?: () => Promise; + export interface UpdateProfileOptions { + displayName?: string; + photoURL?: string; + } + /** - * @deprecated Please use the 'facebookOptions?: FirebaseFacebookLoginOptions' object instead. + * The returned object in the callback handlers + * of the addChildEventListener and addValueEventListener functions. */ - scope?: string[]; -} + export interface FBData { + type: string; + key: string; + value: any; + } + + export interface FBDataSingleEvent extends FBData { + children?: Array; + } + + export interface FBErrorData { + error: string; + } + + export interface AuthStateData { + loggedIn?: boolean; + user?: User; + } + + export interface AuthStateChangeListener { + onAuthStateChanged: (data: AuthStateData) => void; + thisArg?: any; + } + + export interface RemoteConfigProperty { + key: string; + default: any; + } + + export interface GetRemoteConfigOptions { + /** + * Fetch new results from the server more often. + * Default false. + */ + developerMode?: boolean; + /** + * The number of seconds before retrieving fresh state from the server. + * Default 12 hours. + */ + cacheExpirationSeconds?: number; + /** + * The configuration properties to retrieve for your app. Specify as: + * properties: [{ + * key: "holiday_promo_enabled", + * default: false + * }, ..] + */ + properties: Array; + } -export interface ReauthenticateOptions { - type: LoginType; - passwordOptions?: FirebasePasswordLoginOptions; /** - * @deprecated Please use the 'passwordOptions?: FirebasePasswordLoginOptions' object instead. + * The returned object from the getRemoteConfig function. */ - email?: string; + export interface GetRemoteConfigResult { + /** + * The date the data was last refreshed from the server. + * Should honor the 'cacheExpirationSeconds' you passed in previously. + */ + lastFetch: Date; + /** + * The result may be throttled when retrieved from the server. + * Even when the cache has expired. And it's just FYI really. + */ + throttled: boolean; + /** + * A JS Object with properties and values. + * If you previously requested keys ["foo", "is_enabled"] then this will be like: + * properties: { + * foo: "bar", + * is_enabled: true + * } + */ + properties: Object; + } + + export interface DynamicLinkData { + url: string; + minimumAppVersion: string; + } + /** - * @deprecated Please use the 'passwordOptions?: FirebasePasswordLoginOptions' object instead. + * The returned object in the callback handler of the addOnMessageReceivedCallback function. + * + * Note that any custom data you send from your server will be available as + * key/value properties on the Message object as well. */ - password?: string; -} + export interface Message { + /** + * Indicated whether or not the notification was received while the app was in the foreground. + */ + foreground: boolean; + /** + * The main text shown in the notificiation. + * Not available on Android when the notification was received in the background. + */ + body?: string; + /** + * Optional title, shown above the body in the notification. + * Not available on Android when the notification was received in the background. + */ + title?: string; + /** + * Any other data you may have added to the notification. + */ + data: any; + /** + * Indicates whether or not the notification was tapped. + * iOS only. + */ + notificationTapped?: boolean; + } -type ActionCodeSettings = { - url: string; - handleCodeInApp?: boolean; - android?: { - installApp?: boolean; - minimumVersion?: string; - packageName: string; - }; - iOS?: { - bundleId: string; - dynamicLinkDomain?: string; - }; -}; - -/** - * The returned object from the login function. - */ -export interface User { - uid: string; - email?: string; - emailVerified: boolean; - displayName?: string; - phoneNumber?: string; - anonymous: boolean; - isAnonymous: boolean; // This is used by the web API - providers: Array; - photoURL?: string; - metadata: UserMetadata; - additionalUserInfo?: AdditionalUserInfo; - - /** iOS only */ - refreshToken?: string; - - getIdToken(forceRefresh?: boolean): Promise; - - getIdTokenResult(forceRefresh?: boolean): Promise; - - sendEmailVerification(actionCodeSettings?: ActionCodeSettings): Promise; -} + export function init(options?: InitOptions): Promise; -/** - * The metadata of the user - */ -export interface UserMetadata { - creationTimestamp: Date; - lastSignInTimestamp: Date; -} + // Database + export interface OnDisconnect { + cancel(): Promise; -/** - * Contains additional user information - */ -export interface AdditionalUserInfo { - profile: Map; - providerId: string; - username: string; - isNewUser: boolean; -} + remove(): Promise; -/** - * The returned object from the push function. - */ -export interface PushResult { - key: string; -} + set(value: any): Promise; -/** - * The returned object from the addEventListener functions. - */ -export interface AddEventListenerResult { - path: string; - listeners: Array; -} + setWithPriority(value: any, priority: number | string): Promise; -/** - * The options object passed into the createUser function. - */ -export interface CreateUserOptions { - email: string; - password: string; -} + update(values: Object): Promise; + } -/** - * The options object passed into the updateProfile function. - */ -export interface UpdateProfileOptions { - displayName?: string; - photoURL?: string; -} + export interface DataSnapshot { + key: string; + ref: any; // TODO: Type it so that it returns a databaseReference. + child(path: string): DataSnapshot; -/** - * The returned object in the callback handlers - * of the addChildEventListener and addValueEventListener functions. - */ -export interface FBData { - type: string; - key: string; - value: any; -} + exists(): boolean; -export interface FBDataSingleEvent extends FBData { - children?: Array; -} + forEach(action: (snapshot: DataSnapshot) => any): boolean; -export interface FBErrorData { - error: string; -} + getPriority(): string | number | null; -export interface AuthStateData { - loggedIn?: boolean; - user?: User; -} + hasChild(path: string): boolean; -export interface AuthStateChangeListener { - onAuthStateChanged: (data: AuthStateData) => void; - thisArg?: any; -} + hasChildren(): boolean; -export interface RemoteConfigProperty { - key: string; - default: any; -} + numChildren(): number; -export interface GetRemoteConfigOptions { - /** - * Fetch new results from the server more often. - * Default false. - */ - developerMode?: boolean; - /** - * The number of seconds before retrieving fresh state from the server. - * Default 12 hours. - */ - cacheExpirationSeconds?: number; - /** - * The configuration properties to retrieve for your app. Specify as: - * properties: [{ - * key: "holiday_promo_enabled", - * default: false - * }, ..] - */ - properties: Array; -} + toJSON(): Object; -/** - * The returned object from the getRemoteConfig function. - */ -export interface GetRemoteConfigResult { - /** - * The date the data was last refreshed from the server. - * Should honor the 'cacheExpirationSeconds' you passed in previously. - */ - lastFetch: Date; - /** - * The result may be throttled when retrieved from the server. - * Even when the cache has expired. And it's just FYI really. - */ - throttled: boolean; - /** - * A JS Object with properties and values. - * If you previously requested keys ["foo", "is_enabled"] then this will be like: - * properties: { - * foo: "bar", - * is_enabled: true - * } - */ - properties: Object; -} + val(): any; + } -export interface DynamicLinkData { - url: string; - minimumAppVersion: string; -} + export interface FirebaseQueryResult { + type: string; + key: string; + value: any; + } -/** - * The returned object in the callback handler of the addOnMessageReceivedCallback function. - * - * Note that any custom data you send from your server will be available as - * key/value properties on the Message object as well. - */ -export interface Message { - /** - * Indicated whether or not the notification was received while the app was in the foreground. - */ - foreground: boolean; - /** - * The main text shown in the notificiation. - * Not available on Android when the notification was received in the background. - */ - body?: string; - /** - * Optional title, shown above the body in the notification. - * Not available on Android when the notification was received in the background. - */ - title?: string; - /** - * Any other data you may have added to the notification. - */ - data: any; - /** - * Indicates whether or not the notification was tapped. - * iOS only. - */ - notificationTapped?: boolean; -} + export type Unsubscribe = () => void; -export function init(options?: InitOptions): Promise; + export namespace dynamicLinks { + export enum MATCH_CONFIDENCE { + WEAK, + STRONG, + } -// Database -export interface OnDisconnect { - cancel(): Promise; + export interface DynamicLinkCallbackData { + url: string; + matchConfidence?: MATCH_CONFIDENCE; + minimumAppVersion?: string; + } + } + // Auth + export function login(options: LoginOptions): Promise; - remove(): Promise; + export function reauthenticate(options: ReauthenticateOptions): Promise; - set(value: any): Promise; + export function reloadUser(): Promise; - setWithPriority( - value: any, - priority: number | string + export function getAuthToken( + option: GetAuthTokenOptions + ): Promise; + + export function logout(): Promise; + + export function unlink(providerId: string): Promise; + + export function fetchSignInMethodsForEmail( + email: string + ): Promise>; + + export function sendEmailVerification( + actionCodeSettings?: ActionCodeSettings ): Promise; - update(values: Object): Promise; -} + export function createUser(options: CreateUserOptions): Promise; -export interface DataSnapshot { - key: string; - ref: any; // TODO: Type it so that it returns a databaseReference. - child(path: string): DataSnapshot; + export function deleteUser(): Promise; - exists(): boolean; + export function updateProfile(options: UpdateProfileOptions): Promise; - forEach(action: (snapshot: DataSnapshot) => any): boolean; + export function sendPasswordResetEmail(email: string): Promise; - getPriority(): string | number | null; + export function updateEmail(newEmail: string): Promise; - hasChild(path: string): boolean; + export function updatePassword(newPassword: string): Promise; - hasChildren(): boolean; + export function addAuthStateListener( + listener: AuthStateChangeListener + ): boolean; - numChildren(): number; + export function removeAuthStateListener( + listener: AuthStateChangeListener + ): boolean; - toJSON(): Object; + export function hasAuthStateListener( + listener: AuthStateChangeListener + ): boolean; - val(): any; -} + export function getCurrentUser(): Promise; -export interface FirebaseQueryResult { - type: string; - key: string; - value: any; -} + // Messaging + export function addOnMessageReceivedCallback( + onMessageReceived: (data: Message) => void + ): Promise; -export type Unsubscribe = () => void; + export function addOnPushTokenReceivedCallback( + onPushTokenReceived: (data: string) => void + ): Promise; -export function transaction(path: string, transactionUpdate: (a: any) => any, - onComplete?: (error: Error | null, committed: boolean, dataSnapshot: DataSnapshot) => any): Promise; + export function registerForInteractivePush(model: any): void; -export function push(path: string, value: any): Promise; + export function getCurrentPushToken(): Promise; -export function getValue(path: string): Promise; + export function registerForPushNotifications( + options?: MessagingOptions + ): Promise; -export function setValue(path: string, value: any): Promise; + export function unregisterForPushNotifications(): Promise; -export function update(path: string, value: any): Promise; + export function subscribeToTopic(topicName): Promise; -export function remove(path: string): Promise; + export function unsubscribeFromTopic(topicName): Promise; -export function query(onValueEvent: (data: FBData | FBErrorData) => void, path: string, options: QueryOptions): Promise; + export function areNotificationsEnabled(): boolean; -export function addChildEventListener(onChildEvent: (data: FBData) => void, path: string): Promise; + // dynamic links + export function addOnDynamicLinkReceivedCallback( + onDynamicLinkReceived: ( + callBackData: dynamicLinks.DynamicLinkCallbackData + ) => void + ): Promise; -export function addValueEventListener(onValueEvent: (data: FBData) => void, path: string): Promise; + // remote config + export function getRemoteConfig( + options: GetRemoteConfigOptions + ): Promise; + + export function transaction( + path: string, + transactionUpdate: (a: any) => any, + onComplete?: ( + error: Error | null, + committed: boolean, + dataSnapshot: DataSnapshot + ) => any + ): Promise; -export function removeEventListeners(listeners: Array, path: string): Promise; + export function push(path: string, value: any): Promise; -export function onDisconnect(path: string): OnDisconnect; + export function getValue(path: string): Promise; -export function enableLogging(logger?: boolean | ((a: string) => any), persistent?: boolean); + export function setValue(path: string, value: any): Promise; -/** - * Tells the client to keep its local cache in sync with the server automatically. - */ -export function keepInSync(path: string, switchOn: boolean): Promise; + export function update(path: string, value: any): Promise; -export namespace dynamicLinks { - export enum MATCH_CONFIDENCE { - WEAK, - STRONG - } + export function remove(path: string): Promise; - export interface DynamicLinkCallbackData { - url: string; - matchConfidence?: MATCH_CONFIDENCE; - minimumAppVersion?: string; - } + export function query( + onValueEvent: (data: FBData | FBErrorData) => void, + path: string, + options: QueryOptions + ): Promise; + + export function addChildEventListener( + onChildEvent: (data: FBData) => void, + path: string + ): Promise; + + export function addValueEventListener( + onValueEvent: (data: FBData) => void, + path: string + ): Promise; + + export function removeEventListeners( + listeners: Array, + path: string + ): Promise; + + export function onDisconnect(path: string): OnDisconnect; + + export function enableLogging( + logger?: boolean | ((a: string) => any), + persistent?: boolean + ); + + /** + * Tells the client to keep its local cache in sync with the server automatically. + */ + export function keepInSync(path: string, switchOn: boolean): Promise; + + } export namespace firestore { export type DocumentData = { [field: string]: any }; - export type WhereFilterOp = '<' | '<=' | '==' | '>=' | '>' | 'in' | 'array-contains' | 'array-contains-any'; - export type OrderByDirection = 'desc' | 'asc'; + export type WhereFilterOp = + | "<" + | "<=" + | "==" + | ">=" + | ">" + | "in" + | "array-contains" + | "array-contains-any"; + export type OrderByDirection = "desc" | "asc"; export interface GeoPoint { longitude: number; @@ -805,7 +925,7 @@ export namespace firestore { * return an error and `QuerySnapshot.get()` will return an empty * `QuerySnapshot` with no documents. */ - source?: 'default' | 'server' | 'cache'; + source?: "default" | "server" | "cache"; } export interface DocumentReference { @@ -832,7 +952,13 @@ export namespace firestore { delete: () => Promise; - onSnapshot(optionsOrCallback: SnapshotListenOptions | ((snapshot: DocumentSnapshot) => void), callbackOrOnError?: (snapshot: DocumentSnapshot | Error) => void, onError?: (error: Error) => void): () => void; + onSnapshot( + optionsOrCallback: + | SnapshotListenOptions + | ((snapshot: DocumentSnapshot) => void), + callbackOrOnError?: (snapshot: DocumentSnapshot | Error) => void, + onError?: (error: Error) => void + ): () => void; android?: any; @@ -846,11 +972,20 @@ export namespace firestore { where(fieldPath: string, opStr: WhereFilterOp, value: any): Query; - orderBy(fieldPath: string, directionStr: firestore.OrderByDirection): Query; + orderBy( + fieldPath: string, + directionStr: firestore.OrderByDirection + ): Query; limit(limit: number): Query; - onSnapshot(optionsOrCallback: SnapshotListenOptions | ((snapshot: QuerySnapshot) => void), callbackOrOnError?: (snapshotOrError: QuerySnapshot | Error) => void, onError?: (error: Error) => void): () => void; + onSnapshot( + optionsOrCallback: + | SnapshotListenOptions + | ((snapshot: QuerySnapshot) => void), + callbackOrOnError?: (snapshotOrError: QuerySnapshot | Error) => void, + onError?: (error: Error) => void + ): () => void; startAt(snapshot: DocumentSnapshot): Query; @@ -907,21 +1042,39 @@ export namespace firestore { export interface Transaction { get(documentRef: DocumentReference): DocumentSnapshot; - set(documentRef: DocumentReference, data: DocumentData, options?: SetOptions): Transaction; + set( + documentRef: DocumentReference, + data: DocumentData, + options?: SetOptions + ): Transaction; update(documentRef: DocumentReference, data: UpdateData): Transaction; - update(documentRef: DocumentReference, field: string | FieldPath, value: any, ...moreFieldsAndValues: any[]): Transaction; + update( + documentRef: DocumentReference, + field: string | FieldPath, + value: any, + ...moreFieldsAndValues: any[] + ): Transaction; delete(documentRef: DocumentReference): Transaction; } export interface WriteBatch { - set(documentRef: DocumentReference, data: DocumentData, options?: SetOptions): WriteBatch; + set( + documentRef: DocumentReference, + data: DocumentData, + options?: SetOptions + ): WriteBatch; update(documentRef: DocumentReference, data: UpdateData): WriteBatch; - update(documentRef: DocumentReference, field: string | FieldPath, value: any, ...moreFieldsAndValues: any[]): WriteBatch; + update( + documentRef: DocumentReference, + field: string | FieldPath, + value: any, + ...moreFieldsAndValues: any[] + ): WriteBatch; delete(documentRef: DocumentReference): WriteBatch; @@ -959,7 +1112,7 @@ export namespace firestore { * If omitted or set to 'none', `null` will be returned by default until the * server value becomes available. */ - readonly serverTimestamps?: 'estimate' | 'previous' | 'none'; + readonly serverTimestamps?: "estimate" | "previous" | "none"; } export interface QueryDocumentSnapshot extends firestore.DocumentSnapshot { @@ -979,7 +1132,7 @@ export namespace firestore { data(options?: SnapshotOptions): DocumentData; } - export type DocumentChangeType = 'added' | 'removed' | 'modified'; + export type DocumentChangeType = "added" | "removed" | "modified"; export interface DocumentChange { readonly type: DocumentChangeType; @@ -1014,28 +1167,55 @@ export namespace firestore { docChanges(options?: SnapshotListenOptions): DocumentChange[]; - forEach(callback: (result: DocumentSnapshot) => void, thisArg?: any): void; + forEach( + callback: (result: DocumentSnapshot) => void, + thisArg?: any + ): void; } function collection(collectionPath: string): CollectionReference; function collectionGroup(id: string): CollectionGroup; - function doc(collectionPath: string, documentPath?: string): DocumentReference; + function doc( + collectionPath: string, + documentPath?: string + ): DocumentReference; function docRef(documentPath: string): DocumentReference; - function add(collectionPath: string, documentData: any): Promise; - - function set(collectionPath: string, documentPath: string, document: any, options?: any): Promise; - - function getCollection(collectionPath: string, options?: GetOptions): Promise; - - function getDocument(collectionPath: string, documentPath: string, options?: GetOptions): Promise; - - function update(collectionPath: string, documentPath: string, document: any): Promise; - - function runTransaction(updateFunction: (transaction: firestore.Transaction) => Promise): Promise; + function add( + collectionPath: string, + documentData: any + ): Promise; + + function set( + collectionPath: string, + documentPath: string, + document: any, + options?: any + ): Promise; + + function getCollection( + collectionPath: string, + options?: GetOptions + ): Promise; + + function getDocument( + collectionPath: string, + documentPath: string, + options?: GetOptions + ): Promise; + + function update( + collectionPath: string, + documentPath: string, + document: any + ): Promise; + + function runTransaction( + updateFunction: (transaction: firestore.Transaction) => Promise + ): Promise; function batch(): firestore.WriteBatch; @@ -1043,73 +1223,21 @@ export namespace firestore { } export namespace functions { - export type SupportedRegions = "us-central1" | "us-east1" | "us-east4" | "europe-west1" | "europe-west2" | "asia-east2" | "asia-northeast1"; + export type SupportedRegions = + | "us-central1" + | "us-east1" + | "us-east4" + | "europe-west1" + | "europe-west2" + | "asia-east2" + | "asia-northeast1"; export type HttpsCallable = (callableData: I) => Promise; - export function httpsCallable(callableFunctionName: string, region?: SupportedRegions): HttpsCallable; + export function httpsCallable( + callableFunctionName: string, + region?: SupportedRegions + ): HttpsCallable; export function useFunctionsEmulator(origin: string): void; } - -// Auth -export function login(options: LoginOptions): Promise; - -export function reauthenticate(options: ReauthenticateOptions): Promise; - -export function reloadUser(): Promise; - -export function getAuthToken(option: GetAuthTokenOptions): Promise; - -export function logout(): Promise; - -export function unlink(providerId: string): Promise; - -export function fetchSignInMethodsForEmail(email: string): Promise>; - -export function sendEmailVerification(actionCodeSettings?: ActionCodeSettings): Promise; - -export function createUser(options: CreateUserOptions): Promise; - -export function deleteUser(): Promise; - -export function updateProfile(options: UpdateProfileOptions): Promise; - -export function sendPasswordResetEmail(email: string): Promise; - -export function updateEmail(newEmail: string): Promise; - -export function updatePassword(newPassword: string): Promise; - -export function addAuthStateListener(listener: AuthStateChangeListener): boolean; - -export function removeAuthStateListener(listener: AuthStateChangeListener): boolean; - -export function hasAuthStateListener(listener: AuthStateChangeListener): boolean; - -export function getCurrentUser(): Promise; - -// Messaging -export function addOnMessageReceivedCallback(onMessageReceived: (data: Message) => void): Promise; - -export function addOnPushTokenReceivedCallback(onPushTokenReceived: (data: string) => void): Promise; - -export function registerForInteractivePush(model: any): void; - -export function getCurrentPushToken(): Promise; - -export function registerForPushNotifications(options?: MessagingOptions): Promise; - -export function unregisterForPushNotifications(): Promise; - -export function subscribeToTopic(topicName): Promise; - -export function unsubscribeFromTopic(topicName): Promise; - -export function areNotificationsEnabled(): boolean; - -// dynamic links -export function addOnDynamicLinkReceivedCallback(onDynamicLinkReceived: (callBackData: dynamicLinks.DynamicLinkCallbackData) => void): Promise; - -// remote config -export function getRemoteConfig(options: GetRemoteConfigOptions): Promise; diff --git a/src/firebase.ios.ts b/src/firebase.ios.ts index 88a67db1..281b29a3 100755 --- a/src/firebase.ios.ts +++ b/src/firebase.ios.ts @@ -1,13 +1,207 @@ -import * as application from "tns-core-modules/application/application"; -import { device } from "tns-core-modules/platform"; -import { ActionCodeSettings, DataSnapshot, FBDataSingleEvent, firestore, GetAuthTokenOptions, IdTokenResult, OnDisconnect as OnDisconnectBase, QueryOptions, User } from "./firebase"; +import { Application, Device } from "@nativescript/core"; import { DocumentSnapshot as DocumentSnapshotBase, FieldValue, firebase, GeoPoint, isDocumentReference } from "./firebase-common"; import * as firebaseFunctions from "./functions/functions"; import * as firebaseMessaging from "./messaging/messaging"; import { firebaseUtils } from "./utils"; import { getNonce, Sha256 } from "./utils/nonce-util-ios"; +import { firestore } from "./firebase"; declare const ASAuthorizationAppleIDProvider, ASAuthorizationScopeFullName, ASAuthorizationScopeEmail, ASAuthorizationController, ASAuthorizationControllerDelegate, ASAuthorizationAppleIDCredential, ASAuthorizationControllerPresentationContextProviding: any; +export enum QueryOrderByType { + KEY, + VALUE, + CHILD, + PRIORITY +} + +/** + * The allowed values for QueryOptions.range.type. + */ +export enum QueryRangeType { + START_AT, + END_AT, + EQUAL_TO +} + +/** + * The allowed values for QueryOptions.limit.type. + */ +export enum QueryLimitType { + FIRST, + LAST +} +type ActionCodeSettings = { + url: string; + handleCodeInApp?: boolean; + android?: { + installApp?: boolean; + minimumVersion?: string; + packageName: string; + }; + iOS?: { + bundleId: string; + dynamicLinkDomain?: string; + }; +}; +export interface OnDisconnectBase { + cancel(): Promise; + + remove(): Promise; + + set(value: any): Promise; + + setWithPriority( + value: any, + priority: number | string + ): Promise; + + update(values: Object): Promise; +} + + +export interface DataSnapshot { + key: string; + ref: any; // TODO: Type it so that it returns a databaseReference. + child(path: string): DataSnapshot; + + exists(): boolean; + + forEach(action: (snapshot: DataSnapshot) => any): boolean; + + getPriority(): string | number | null; + + hasChild(path: string): boolean; + + hasChildren(): boolean; + + numChildren(): number; + + toJSON(): Object; + + val(): any; +} + +export interface FBData { + type: string; + key: string; + value: any; +} + +export interface FBDataSingleEvent extends FBData { + children?: Array; +} + +export interface FBErrorData { + error: string; +} + +export interface GetAuthTokenOptions { + /** + * Default false. + */ + forceRefresh?: boolean; +} +export interface IdTokenResult { + token: string; + claims: { [key: string]: any; }; + signInProvider: string; + expirationTime: number; + issuedAtTime: number; + authTime: number; +} +export interface QueryRangeOption { + type: QueryRangeType; + value: any; +} + +/** + * The options object passed into the query function. + */ +export interface QueryOptions { + /** + * How you'd like to sort the query result. + */ + orderBy: { + type: QueryOrderByType; + /** + * mandatory when type is QueryOrderByType.CHILD + */ + value?: string; + }; + + /** + * You can further restrict the returned results by specifying restrictions. + * Need more than one range restriction? Use 'ranges' instead. + */ + range?: QueryRangeOption; + + /** + * Same as 'range', but for a 'chain of ranges'. + * You can further restrict the returned results by specifying restrictions. + */ + ranges?: QueryRangeOption[]; + + /** + * You can limit the number of returned rows if you want to. + */ + limit?: { + type: QueryLimitType; + value: number; + }; + + /** + * Set this to true if you don't want to listen for any future updates, + * but just want to retrieve the current value. + * You can also use this to check if certain data is in the database. + * Default false. + */ + singleEvent?: boolean; +} +export interface Provider { + id: string; + token?: string; +} + +export interface User { + uid: string; + email?: string; + emailVerified: boolean; + displayName?: string; + phoneNumber?: string; + anonymous: boolean; + isAnonymous: boolean; // This is used by the web API + providers: Array; + photoURL?: string; + metadata: UserMetadata; + additionalUserInfo?: AdditionalUserInfo; + + /** iOS only */ + refreshToken?: string; + + getIdToken(forceRefresh?: boolean): Promise; + + getIdTokenResult(forceRefresh?: boolean): Promise; + + sendEmailVerification(actionCodeSettings?: ActionCodeSettings): Promise; +} + +/** + * The metadata of the user + */ +export interface UserMetadata { + creationTimestamp: Date; + lastSignInTimestamp: Date; +} + +/** + * Contains additional user information + */ +export interface AdditionalUserInfo { + profile: Map; + providerId: string; + username: string; + isNewUser: boolean; +} firebase._gIDAuthentication = null; firebase._cachedDynamicLink = null; @@ -284,15 +478,16 @@ if (typeof (FIRMessaging) !== "undefined" || useExternalPushProvider) { // This breaks in-app-messaging :( function getAppDelegate() { // Play nice with other plugins by not completely ignoring anything already added to the appdelegate - if (application.ios.delegate === undefined) { + if (Application.ios.delegate === undefined) { @ObjCClass(UIApplicationDelegate) + @NativeClass() class UIApplicationDelegateImpl extends UIResponder implements UIApplicationDelegate { } - application.ios.delegate = UIApplicationDelegateImpl; + Application.ios.delegate = UIApplicationDelegateImpl; } - return application.ios.delegate; + return Application.ios.delegate; } firebase.addAppDelegateMethods(getAppDelegate()); @@ -803,7 +998,7 @@ firebase.login = arg => { return; } // The link was successfully sent. - // Save the email locally so you don't need to ask the user for it again if they open the link on the same device. + // Save the email locally so you don't need to ask the user for it again if they open the link on the same Device. firebase.rememberEmailForEmailLinkLogin(arg.emailLinkOptions.email); resolve(); } @@ -914,8 +1109,8 @@ firebase.login = arg => { onFacebookCompletion); } else if (arg.type === firebase.LoginType.APPLE) { - if (parseInt(device.osVersion) < 13) { - reject("Sign in with Apple requires iOS 13 or higher. You're running iOS " + device.osVersion); + if (parseInt(Device.osVersion) < 13) { + reject("Sign in with Apple requires iOS 13 or higher. You're running iOS " + Device.osVersion); return; } @@ -958,7 +1153,7 @@ firebase.login = arg => { } const sIn = GIDSignIn.sharedInstance(); - sIn.presentingViewController = arg.ios && arg.ios.controller ? arg.ios.controller : application.ios.rootController; + sIn.presentingViewController = arg.ios && arg.ios.controller ? arg.ios.controller : Application.ios.rootController; sIn.clientID = FIRApp.defaultApp().options.clientID; if (arg.googleOptions && arg.googleOptions.hostedDomain) { @@ -1727,18 +1922,18 @@ firebase.firestore.WriteBatch = (nativeWriteBatch: FIRWriteBatch): firestore.Wri public set = (documentRef: firestore.DocumentReference, data: firestore.DocumentData, options?: firestore.SetOptions): firestore.WriteBatch => { fixSpecialFields(data); - nativeWriteBatch.setDataForDocumentMerge(data, documentRef.ios, options && options.merge); + nativeWriteBatch.setDataForDocumentMerge(data, (documentRef).ios, options && options.merge); return this; } public update = (documentRef: firestore.DocumentReference, data: firestore.UpdateData): firestore.WriteBatch => { fixSpecialFields(data); - nativeWriteBatch.updateDataForDocument(data, documentRef.ios); + nativeWriteBatch.updateDataForDocument(data, (documentRef).ios); return this; } public delete = (documentRef: firestore.DocumentReference): firestore.WriteBatch => { - nativeWriteBatch.deleteDocument(documentRef.ios); + nativeWriteBatch.deleteDocument((documentRef).ios); return this; } @@ -1759,31 +1954,31 @@ firebase.firestore.batch = (): firestore.WriteBatch => { return new firebase.firestore.WriteBatch(FIRFirestore.firestore().batch()); }; -firebase.firestore.Transaction = (nativeTransaction: FIRTransaction): firestore.Transaction => { +firebase.firestore.Transaction = (nativeTransaction: FIRTransaction): any => { //firestore.Transaction class FirestoreTransaction implements firestore.Transaction { constructor() { } - public get = (documentRef: firestore.DocumentReference): DocumentSnapshot => { - const docSnapshot: FIRDocumentSnapshot = nativeTransaction.getDocumentError(documentRef.ios); + public get: any = (documentRef: firestore.DocumentReference): DocumentSnapshot => { + const docSnapshot: FIRDocumentSnapshot = nativeTransaction.getDocumentError((documentRef).ios); return new DocumentSnapshot(docSnapshot); } public set = (documentRef: firestore.DocumentReference, data: firestore.DocumentData, options?: firestore.SetOptions): firestore.Transaction => { fixSpecialFields(data); - nativeTransaction.setDataForDocumentMerge(data, documentRef.ios, options && options.merge); - return this; + nativeTransaction.setDataForDocumentMerge(data, (documentRef).ios, options && options.merge); + return this; } public update = (documentRef: firestore.DocumentReference, data: firestore.UpdateData): firestore.Transaction => { fixSpecialFields(data); - nativeTransaction.updateDataForDocument(data, documentRef.ios); - return this; + nativeTransaction.updateDataForDocument(data, (documentRef).ios); + return this; } public delete = (documentRef: firestore.DocumentReference): firestore.Transaction => { - nativeTransaction.deleteDocument(documentRef.ios); - return this; + nativeTransaction.deleteDocument((documentRef).ios); + return this; } } @@ -1810,7 +2005,7 @@ firebase.firestore.settings = (settings: firestore.Settings) => { if (settings.ssl !== undefined) fIRFirestoreSettings.sslEnabled = settings.ssl; if (settings.host !== undefined) fIRFirestoreSettings.host = settings.host; // Cannot do this because of nativescript cannot convert Number to int64_t - // fIRFirestoreSettings.cacheSizeBytes = settings.cacheSizeBytes; + // fIRFirestore(settings).cacheSizeBytes = (settings).cacheSizeBytes; FIRFirestore.firestore().settings = fIRFirestoreSettings; } catch (err) { console.log("Error in firebase.firestore.settings: " + err); @@ -1837,7 +2032,7 @@ firebase.firestore.collection = (collectionPath: string): firestore.CollectionRe } }; -firebase.firestore.collectionGroup = (id: string): firestore.CollectionGroup => { +firebase.firestore.collectionGroup = (id: string): any => { ensureFirestore(); try { return firebase.firestore._getCollectionGroupQuery(FIRFirestore.firestore().collectionGroupWithID(id)); @@ -1948,7 +2143,7 @@ firebase.firestore._getCollectionReference = (colRef?: FIRCollectionReference): }; }; -firebase.firestore._getCollectionGroupQuery = (query?: FIRQuery): firestore.CollectionGroup => { +firebase.firestore._getCollectionGroupQuery = (query?: FIRQuery): any => { if (!query) { return null; } @@ -1976,7 +2171,7 @@ firebase.firestore._getDocumentReference = (docRef?: FIRDocumentReference): fire get: (options?: firestore.GetOptions) => firebase.firestore.getDocument(collectionPath, docRef.documentID, options), update: (data: any) => firebase.firestore.update(collectionPath, docRef.documentID, data), delete: () => firebase.firestore.delete(collectionPath, docRef.documentID), - onSnapshot: (optionsOrCallback: firestore.SnapshotListenOptions | ((snapshot: DocumentSnapshot) => void), callbackOrOnError?: (docOrError: DocumentSnapshot | Error) => void, onError?: (error: Error) => void) => firebase.firestore.onDocumentSnapshot(docRef, optionsOrCallback, callbackOrOnError, onError), + onSnapshot: (optionsOrCallback: firestore.SnapshotListenOptions | ((snapshot: firestore.DocumentSnapshot) => void), callbackOrOnError?: (docOrError: firestore.DocumentSnapshot | Error) => void, onError?: (error: Error) => void) => firebase.firestore.onDocumentSnapshot(docRef, optionsOrCallback, callbackOrOnError, onError), ios: docRef }; }; @@ -2097,7 +2292,7 @@ function fixSpecialField(item): any { longitude: geo.longitude }); } else if (isDocumentReference(item)) { - return item.ios; + return (item).ios; } else if (typeof item === "object" && item.constructor === Object) { return fixSpecialFields(item); } else { @@ -2187,7 +2382,7 @@ firebase.firestore.get = (collectionPath: string, options?: firestore.GetOptions return firebase.firestore.getCollection(collectionPath, options); }; -firebase.firestore.getDocument = (collectionPath: string, documentPath: string, options?: firestore.GetOptions): Promise => { +firebase.firestore.getDocument = (collectionPath: string, documentPath: string, options?: firestore.GetOptions): Promise => { ensureFirestore(); return new Promise((resolve, reject) => { try { @@ -2207,7 +2402,7 @@ firebase.firestore.getDocument = (collectionPath: string, documentPath: string, if (error) { reject(error.localizedDescription); } else { - resolve(new DocumentSnapshot(snapshot)); + resolve(new DocumentSnapshot(snapshot)); } }); @@ -2318,6 +2513,7 @@ firebase.firestore.endBefore = (collectionPath: string, snapshotOrFieldValue: Do } }; +@NativeClass() class GIDSignInDelegateImpl extends NSObject implements GIDSignInDelegate { public static ObjCProtocols = []; @@ -2354,7 +2550,7 @@ function convertDocChangeType(type: FIRDocumentChangeType) { } function convertDocument(qDoc: FIRQueryDocumentSnapshot): firestore.QueryDocumentSnapshot { - return new DocumentSnapshot(qDoc); + return new DocumentSnapshot(qDoc); } export class QuerySnapshot implements firestore.QuerySnapshot { @@ -2373,7 +2569,7 @@ export class QuerySnapshot implements firestore.QuerySnapshot { const docSnapshots: firestore.QueryDocumentSnapshot[] = []; for (let i = 0, l = this.snapshot.documents.count; i < l; i++) { const document = this.snapshot.documents.objectAtIndex(i); - docSnapshots.push(new DocumentSnapshot(document)); + docSnapshots.push(new DocumentSnapshot(document)); } this._docSnapshots = docSnapshots; @@ -2416,6 +2612,7 @@ export class QuerySnapshot implements firestore.QuerySnapshot { } } +@NativeClass() class ASAuthorizationControllerDelegateImpl extends NSObject /* implements ASAuthorizationControllerDelegate */ { public static ObjCProtocols = []; private owner: any; @@ -2424,7 +2621,7 @@ class ASAuthorizationControllerDelegateImpl extends NSObject /* implements ASAut public static createWithOwnerAndResolveReject(owner: any, resolve, reject): ASAuthorizationControllerDelegateImpl { // defer initialisation because this is only available since iOS 13 - if (ASAuthorizationControllerDelegateImpl.ObjCProtocols.length === 0 && parseInt(device.osVersion) >= 13) { + if (ASAuthorizationControllerDelegateImpl.ObjCProtocols.length === 0 && parseInt(Device.osVersion) >= 13) { ASAuthorizationControllerDelegateImpl.ObjCProtocols.push(ASAuthorizationControllerDelegate); } let delegate = ASAuthorizationControllerDelegateImpl.new(); @@ -2481,13 +2678,14 @@ class ASAuthorizationControllerDelegateImpl extends NSObject /* implements ASAut } } +@NativeClass() class ASAuthorizationControllerPresentationContextProvidingImpl extends NSObject /* implements ASAuthorizationControllerDelegate */ { public static ObjCProtocols = []; private owner: any; public static createWithOwnerAndCallback(owner: any): ASAuthorizationControllerPresentationContextProvidingImpl { // defer initialisation because this is only available since iOS 13 - if (ASAuthorizationControllerPresentationContextProvidingImpl.ObjCProtocols.length === 0 && parseInt(device.osVersion) >= 13) { + if (ASAuthorizationControllerPresentationContextProvidingImpl.ObjCProtocols.length === 0 && parseInt(Device.osVersion) >= 13) { ASAuthorizationControllerPresentationContextProvidingImpl.ObjCProtocols.push(ASAuthorizationControllerPresentationContextProviding); } let delegate = ASAuthorizationControllerPresentationContextProvidingImpl.new(); @@ -2500,4 +2698,4 @@ class ASAuthorizationControllerPresentationContextProvidingImpl extends NSObject } } -module.exports = firebase; +export * from './firebase-common'; diff --git a/src/inappmessaging/inappmessaging.ios.ts b/src/inappmessaging/inappmessaging.ios.ts index b046787d..d3946051 100644 --- a/src/inappmessaging/inappmessaging.ios.ts +++ b/src/inappmessaging/inappmessaging.ios.ts @@ -22,6 +22,7 @@ function ensureDelegate(): void { } } +@NativeClass() class FIRInAppMessagingDisplayDelegateImpl extends NSObject implements FIRInAppMessagingDisplayDelegate { public static ObjCProtocols = []; diff --git a/src/messaging/index.ts b/src/messaging/index.ts index 9859c69c..671a9f23 100644 --- a/src/messaging/index.ts +++ b/src/messaging/index.ts @@ -1,5 +1,3 @@ -import { Message } from "../firebase"; import * as msging from "./messaging"; export const messaging = msging; -export { Message }; diff --git a/src/messaging/messaging.android.ts b/src/messaging/messaging.android.ts index 912ff178..06132d46 100755 --- a/src/messaging/messaging.android.ts +++ b/src/messaging/messaging.android.ts @@ -1,8 +1,7 @@ import { firebase } from "../firebase-common"; -import * as appModule from "tns-core-modules/application"; -import * as application from "tns-core-modules/application/application"; +import { Application } from "@nativescript/core"; import { PushNotificationModel } from "./messaging.ios"; -import { MessagingOptions } from "../firebase"; +import { firebase as fbNamespace } from "../firebase"; declare const android, com, global: any; const NotificationManagerCompatClass = useAndroidX() ? global.androidx.core.app.NotificationManagerCompat : android.support.v4.app.NotificationManagerCompat; @@ -17,24 +16,24 @@ function getSenderId(): Promise { } const setSenderIdAndResolve = () => { - const senderIdResourceId = application.android.context.getResources().getIdentifier("gcm_defaultSenderId", "string", application.android.context.getPackageName()); + const senderIdResourceId = Application.android.context.getResources().getIdentifier("gcm_defaultSenderId", "string", Application.android.context.getPackageName()); if (senderIdResourceId === 0) { throw new Error("####################### Seems like you did not include 'google-services.json' in your project! Firebase Messaging will not work properly. #######################"); } - _senderId = application.android.context.getString(senderIdResourceId); + _senderId = Application.android.context.getString(senderIdResourceId); resolve(_senderId); }; - if (!application.android.context) { + if (!Application.android.context) { // throw new Error("Don't call this function before your app has started."); - appModule.on(appModule.launchEvent, () => setSenderIdAndResolve()) + Application.on(Application.launchEvent, () => setSenderIdAndResolve()) } else { setSenderIdAndResolve(); } }); } -export function initFirebaseMessaging(options?: MessagingOptions) { +export function initFirebaseMessaging(options?: fbNamespace.MessagingOptions) { if (!options) { return; } @@ -47,7 +46,7 @@ export function initFirebaseMessaging(options?: MessagingOptions) { } export function onAppModuleLaunchEvent(args: any) { - org.nativescript.plugins.firebase.FirebasePluginLifecycleCallbacks.registerCallbacks(appModule.android.nativeApp); + org.nativescript.plugins.firebase.FirebasePluginLifecycleCallbacks.registerCallbacks(Application.android.nativeApp); } export function onAppModuleResumeEvent(args: any) { @@ -175,7 +174,7 @@ export function addOnPushTokenReceivedCallback(callback) { }); } -export function registerForPushNotifications(options?: MessagingOptions): Promise { +export function registerForPushNotifications(options?: fbNamespace.MessagingOptions): Promise { return new Promise((resolve, reject) => { try { if (typeof (com.google.firebase.messaging) === "undefined") { @@ -270,7 +269,7 @@ export function areNotificationsEnabled() { const androidSdkVersion = android.os.Build.VERSION.SDK_INT; if (androidSdkVersion >= 24) { // android.os.Build.VERSION_CODES.N - return NotificationManagerCompatClass.from(application.android.context).areNotificationsEnabled(); + return NotificationManagerCompatClass.from(Application.android.context).areNotificationsEnabled(); } else { console.log("NotificationManagerCompat.areNotificationsEnabled() is not supported in Android SDK VERSION " + androidSdkVersion); return true; diff --git a/src/messaging/messaging.ios.ts b/src/messaging/messaging.ios.ts index 05bf3ade..c7b227d7 100755 --- a/src/messaging/messaging.ios.ts +++ b/src/messaging/messaging.ios.ts @@ -1,8 +1,6 @@ -import { DelegateObserver, SharedNotificationDelegate } from "nativescript-shared-notification-delegate"; -import * as applicationSettings from "tns-core-modules/application-settings"; -import * as application from "tns-core-modules/application/application"; -import { device } from "tns-core-modules/platform/platform"; -import { MessagingOptions } from "../firebase"; +import { DelegateObserver, SharedNotificationDelegate } from "@nativescript/shared-notification-delegate"; +import { Application, ApplicationSettings, Device } from "@nativescript/core"; +import { firebase as fbNamespace } from "../firebase"; import { firebase } from "../firebase-common"; import { firebaseUtils } from "../utils"; import { IosInteractiveNotificationAction, IosInteractiveNotificationCategory, IosInteractiveNotificationType } from "./messaging"; @@ -47,7 +45,7 @@ export function initFirebaseMessaging(options) { export function addOnMessageReceivedCallback(callback: Function) { return new Promise((resolve, reject) => { try { - applicationSettings.setBoolean(NOTIFICATIONS_REGISTRATION_KEY, true); + ApplicationSettings.setBoolean(NOTIFICATIONS_REGISTRATION_KEY, true); _receivedNotificationCallback = callback; _registerForRemoteNotifications(resolve, reject); @@ -76,7 +74,7 @@ export function getCurrentPushToken(): Promise { }); } -export function registerForPushNotifications(options?: MessagingOptions): Promise { +export function registerForPushNotifications(options?: fbNamespace.MessagingOptions): Promise { return new Promise((resolve, reject) => { try { initFirebaseMessaging(options); @@ -94,11 +92,11 @@ export function unregisterForPushNotifications(): Promise { try { UIApplication.sharedApplication.unregisterForRemoteNotifications(); - // Note that we're not removing this key, because upon restart it would re-register the device. + // Note that we're not removing this key, because upon restart it would re-register the Device. // I mean, if the dev uses 'unregisterForPushNotifications', he will likely also want to explicitly use 'registerForPushNotifications'. // TODO toch de key maar verwijderen? - // applicationSettings.remove(NOTIFICATIONS_REGISTRATION_KEY); + // ApplicationSettings.remove(NOTIFICATIONS_REGISTRATION_KEY); resolve(); } catch (ex) { @@ -138,7 +136,7 @@ export function addOnPushTokenReceivedCallback(callback) { callback(_pushToken); } - applicationSettings.setBoolean(NOTIFICATIONS_REGISTRATION_KEY, true); + ApplicationSettings.setBoolean(NOTIFICATIONS_REGISTRATION_KEY, true); _registerForRemoteNotifications(); _processPendingNotifications(); @@ -244,7 +242,7 @@ export function prepAppDelegate() { _addObserver("com.firebase.iid.notif.refresh-token", notification => onTokenRefreshNotification(notification.object)); _addObserver(UIApplicationDidFinishLaunchingNotification, appNotification => { - if (applicationSettings.getBoolean(NOTIFICATIONS_REGISTRATION_KEY, false)) { + if (ApplicationSettings.getBoolean(NOTIFICATIONS_REGISTRATION_KEY, false)) { _registerForRemoteNotifications(); } }); @@ -358,7 +356,7 @@ const updateUserInfo = userInfoJSON => { function _registerForRemoteNotifications(resolve?, reject?) { let app = UIApplication.sharedApplication; if (!app) { - application.on("launch", () => _registerForRemoteNotifications(resolve, reject)); + Application.on(Application.launchEvent, () => _registerForRemoteNotifications(resolve, reject)); return; } @@ -372,7 +370,7 @@ function _registerForRemoteNotifications(resolve?, reject?) { _resolveWhenDidRegisterForNotifications = resolve; _rejectWhenDidFailToRegisterForNotifications = reject; - if (parseInt(device.osVersion) >= 10) { + if (parseInt(Device.osVersion) >= 10) { const authorizationOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Sound | UNAuthorizationOptions.Badge; UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptionsCompletionHandler(authorizationOptions, (granted, error) => { if (!error) { @@ -476,7 +474,7 @@ function _addOnNotificationActionTakenCallback(callback: Function) { function _processPendingNotifications() { const app = UIApplication.sharedApplication; if (!app) { - application.on("launch", () => _processPendingNotifications()); + Application.on("launch", () => _processPendingNotifications()); return; } if (_receivedNotificationCallback) { @@ -494,7 +492,7 @@ function _processPendingNotifications() { function _processPendingActionTakenNotifications() { const app = UIApplication.sharedApplication; if (!app) { - application.on("launch", () => _processPendingNotifications()); + Application.on("launch", () => _processPendingNotifications()); return; } if (_notificationActionTakenCallback) { @@ -559,6 +557,7 @@ class FirebaseNotificationDelegateObserverImpl implements DelegateObserver { } } +@NativeClass() class FIRMessagingDelegateImpl extends NSObject implements FIRMessagingDelegate { public static ObjCProtocols = []; diff --git a/src/mlkit/automl/automl-common.ts b/src/mlkit/automl/automl-common.ts index 53fd4314..6979dee8 100644 --- a/src/mlkit/automl/automl-common.ts +++ b/src/mlkit/automl/automl-common.ts @@ -1,4 +1,4 @@ -import { Property } from "tns-core-modules/ui/core/properties"; +import { Property } from "@nativescript/core"; import { MLKitCameraView } from "../mlkit-cameraview"; export const localModelResourceFolderProperty = new Property({ diff --git a/src/mlkit/automl/index.android.ts b/src/mlkit/automl/index.android.ts index d0558fd7..4b264046 100644 --- a/src/mlkit/automl/index.android.ts +++ b/src/mlkit/automl/index.android.ts @@ -1,4 +1,4 @@ -import { ImageSource } from "tns-core-modules/image-source"; +import { ImageSource } from "@nativescript/core"; import { MLKitVisionOptions, } from "../"; import { MLKitAutoMLOptions, MLKitAutoMLResult } from "./"; import { MLKitAutoML as MLKitAutoMLBase } from "./automl-common"; diff --git a/src/mlkit/automl/index.ios.ts b/src/mlkit/automl/index.ios.ts index c9528d3f..074a3c5c 100644 --- a/src/mlkit/automl/index.ios.ts +++ b/src/mlkit/automl/index.ios.ts @@ -1,4 +1,4 @@ -import { ImageSource } from "tns-core-modules/image-source"; +import { ImageSource } from "@nativescript/core"; import { MLKitAutoMLResult, MLKitAutoMLOptions } from "./index"; import { MLKitVisionOptions } from "../index"; import { MLKitAutoML as MLKitAutoMLBase } from "./automl-common"; diff --git a/src/mlkit/barcodescanning/barcodescanning-common.ts b/src/mlkit/barcodescanning/barcodescanning-common.ts index b94193cd..f90f29d4 100644 --- a/src/mlkit/barcodescanning/barcodescanning-common.ts +++ b/src/mlkit/barcodescanning/barcodescanning-common.ts @@ -1,5 +1,4 @@ -import { booleanConverter } from "tns-core-modules/ui/core/view-base"; -import { Property } from "tns-core-modules/ui/core/properties"; +import { booleanConverter, Property } from "@nativescript/core"; import { MLKitCameraView } from "../mlkit-cameraview"; export enum BarcodeFormat { diff --git a/src/mlkit/barcodescanning/index.android.ts b/src/mlkit/barcodescanning/index.android.ts index 6855fac0..75dcc9dd 100644 --- a/src/mlkit/barcodescanning/index.android.ts +++ b/src/mlkit/barcodescanning/index.android.ts @@ -1,7 +1,6 @@ -import { ImageSource } from "tns-core-modules/image-source"; +import { ImageSource, Application } from "@nativescript/core"; import { MLKitScanBarcodesOnDeviceOptions, MLKitScanBarcodesOnDeviceResult, MLKitScanBarcodesResultBounds } from "./"; import { BarcodeFormat, MLKitBarcodeScanner as MLKitBarcodeScannerBase } from "./barcodescanning-common"; -import * as application from "tns-core-modules/application"; export { BarcodeFormat }; @@ -29,15 +28,15 @@ export class MLKitBarcodeScanner extends MLKitBarcodeScannerBase { } if (this.beepOnScan) { - const activity = (application.android.foregroundActivity || application.android.startActivity); + const activity = (Application.android.foregroundActivity || Application.android.startActivity); activity.setVolumeControlStream(android.media.AudioManager.STREAM_MUSIC); try { - const file = application.android.context.getResources().getIdentifier("beep", "raw", application.android.context.getPackageName()); + const file = Application.android.context.getResources().getIdentifier("beep", "raw", Application.android.context.getPackageName()); if (file === 0) { console.log("No 'beep.*' soundfile found in the resources /raw folder. There will be no audible feedback upon scanning a barcode."); } else { this.player = new android.media.MediaPlayer(); - const fileDescriptor: android.content.res.AssetFileDescriptor = application.android.context.getResources().openRawResourceFd(file); + const fileDescriptor: android.content.res.AssetFileDescriptor = Application.android.context.getResources().openRawResourceFd(file); try { this.player.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getLength()); } finally { diff --git a/src/mlkit/barcodescanning/index.ios.ts b/src/mlkit/barcodescanning/index.ios.ts index a253e162..165b8857 100644 --- a/src/mlkit/barcodescanning/index.ios.ts +++ b/src/mlkit/barcodescanning/index.ios.ts @@ -1,5 +1,4 @@ -import { ImageSource } from "tns-core-modules/image-source"; -import { ios as iosUtils } from "tns-core-modules/utils/utils"; +import { ImageSource, Utils } from "@nativescript/core"; import { MLKitScanBarcodesOnDeviceOptions, MLKitScanBarcodesOnDeviceResult } from "./index"; import { BarcodeFormat, MLKitBarcodeScanner as MLKitBarcodeScannerBase } from "./barcodescanning-common"; @@ -58,7 +57,7 @@ export class MLKitBarcodeScanner extends MLKitBarcodeScannerBase { const origWidth = width; const origImageWidth = imageWidth; - if (iosUtils.isLandscape()) { + if (Utils.ios.isLandscape()) { if (UIDevice.currentDevice.orientation === UIDeviceOrientation.LandscapeRight) { // the image is rotated 180 degrees x = image.size.width - (width + x); diff --git a/src/mlkit/custommodel/custommodel-common.ts b/src/mlkit/custommodel/custommodel-common.ts index 5268d08f..c211ff98 100644 --- a/src/mlkit/custommodel/custommodel-common.ts +++ b/src/mlkit/custommodel/custommodel-common.ts @@ -1,5 +1,4 @@ -import * as fs from "tns-core-modules/file-system"; -import { Property } from "tns-core-modules/ui/core/properties"; +import { knownFolders, File, Property } from "@nativescript/core"; import { MLKitCameraView } from "../mlkit-cameraview"; import { MLKitCustomModelType } from "./index"; @@ -79,12 +78,12 @@ modelInputShapeProperty.register(MLKitCustomModel); modelInputTypeProperty.register(MLKitCustomModel); export function getLabelsFromAppFolder(labelsFile: string): Array { - const labelsPath = fs.knownFolders.currentApp().path + labelsFile.substring(1); + const labelsPath = knownFolders.currentApp().path + labelsFile.substring(1); return getLabelsFromFile(labelsPath); } export function getLabelsFromFile(labelsFile: string): Array { - const fileContents = fs.File.fromPath(labelsFile).readTextSync(); + const fileContents = File.fromPath(labelsFile).readTextSync(); const lines: Array = fileContents.split("\n"); // remove possibly empty trailing lines while (lines[lines.length - 1].trim() === "") { diff --git a/src/mlkit/custommodel/index.android.ts b/src/mlkit/custommodel/index.android.ts index 34d87fb8..cc151283 100644 --- a/src/mlkit/custommodel/index.android.ts +++ b/src/mlkit/custommodel/index.android.ts @@ -1,5 +1,4 @@ -import * as fs from "tns-core-modules/file-system"; -import { ImageSource } from "tns-core-modules/image-source"; +import { ImageSource, knownFolders } from "@nativescript/core"; import { MLKitCustomModelOptions, MLKitCustomModelResult, MLKitCustomModelResultValue } from "./"; import { getLabelsFromAppFolder, MLKitCustomModel as MLKitCustomModelBase } from "./custommodel-common"; @@ -111,7 +110,7 @@ function getInterpreter(localModelFile?: string): any { // const firModelLocalBuilder = new com.google.firebase.ml.common.modeldownload.FirebaseLocalModel.Builder(localModelName); if (localModelFile.indexOf("~/") === 0) { - localModelBuilder.setFilePath(fs.knownFolders.currentApp().path + localModelFile.substring(1)); + localModelBuilder.setFilePath(knownFolders.currentApp().path + localModelFile.substring(1)); } else { // note that this doesn't seem to work, let's advice users to use ~/ for now (TODO check if this is still te case) localModelBuilder.setAssetFilePath(localModelFile); diff --git a/src/mlkit/custommodel/index.ios.ts b/src/mlkit/custommodel/index.ios.ts index 9a43eeaf..abe2aa2e 100644 --- a/src/mlkit/custommodel/index.ios.ts +++ b/src/mlkit/custommodel/index.ios.ts @@ -1,5 +1,4 @@ -import * as fs from "tns-core-modules/file-system"; -import { ImageSource } from "tns-core-modules/image-source"; +import { ImageSource, knownFolders } from "@nativescript/core"; import { MLKitCustomModelOptions, MLKitCustomModelResult, MLKitCustomModelResultValue } from "./"; import { getLabelsFromAppFolder, @@ -105,7 +104,7 @@ function getInterpreter(localModelFile: string): FIRModelInterpreter { let localModelFilePath: string; if (localModelFile.indexOf("~/") === 0) { - localModelFilePath = fs.knownFolders.currentApp().path + localModelFile.substring(1); + localModelFilePath = knownFolders.currentApp().path + localModelFile.substring(1); } else { localModelFilePath = NSBundle.mainBundle.pathForResourceOfType( localModelFile.substring(0, localModelFile.lastIndexOf(".")), diff --git a/src/mlkit/facedetection/facedetection-common.ts b/src/mlkit/facedetection/facedetection-common.ts index 9a8708a5..18a082a2 100644 --- a/src/mlkit/facedetection/facedetection-common.ts +++ b/src/mlkit/facedetection/facedetection-common.ts @@ -1,5 +1,4 @@ -import { booleanConverter, makeParser, makeValidator } from "tns-core-modules/ui/core/view-base"; -import { Property } from "tns-core-modules/ui/core/properties"; +import { Property, booleanConverter, makeParser, makeValidator } from "@nativescript/core"; import { MLKitCameraView } from "../mlkit-cameraview"; import { MLKitFaceDetectionMode } from "./"; diff --git a/src/mlkit/facedetection/index.android.ts b/src/mlkit/facedetection/index.android.ts index ecbfb993..e327df00 100644 --- a/src/mlkit/facedetection/index.android.ts +++ b/src/mlkit/facedetection/index.android.ts @@ -1,4 +1,4 @@ -import { ImageSource } from "tns-core-modules/image-source"; +import { ImageSource } from "@nativescript/core"; import { MLKitDetectFacesOnDeviceOptions, MLKitDetectFacesOnDeviceResult, MLKitDetectFacesResultBounds } from "./"; import { MLKitVisionOptions } from "../"; import { MLKitFaceDetection as MLKitFaceDetectionBase } from "./facedetection-common"; diff --git a/src/mlkit/facedetection/index.ios.ts b/src/mlkit/facedetection/index.ios.ts index 09a4c0c5..b6818462 100644 --- a/src/mlkit/facedetection/index.ios.ts +++ b/src/mlkit/facedetection/index.ios.ts @@ -1,5 +1,4 @@ -import { ImageSource } from "tns-core-modules/image-source"; -import { ios as iosUtils } from "tns-core-modules/utils/utils"; +import { ImageSource, Utils } from "@nativescript/core"; import { MLKitVisionOptions } from "../"; import { MLKitDetectFacesOnDeviceOptions, MLKitDetectFacesOnDeviceResult } from "./"; import { MLKitFaceDetection as MLKitFaceDetectionBase } from "./facedetection-common"; @@ -51,7 +50,7 @@ export class MLKitFaceDetection extends MLKitFaceDetectionBase { } getVisionOrientation(imageOrientation: UIImageOrientation): FIRVisionDetectorImageOrientation { - if (imageOrientation === UIImageOrientation.Up && !iosUtils.isLandscape()) { + if (imageOrientation === UIImageOrientation.Up && !Utils.ios.isLandscape()) { return FIRVisionDetectorImageOrientation.RightTop; } else { return super.getVisionOrientation(imageOrientation); diff --git a/src/mlkit/imagelabeling/imagelabeling-common.ts b/src/mlkit/imagelabeling/imagelabeling-common.ts index e1fad84d..69425e3b 100644 --- a/src/mlkit/imagelabeling/imagelabeling-common.ts +++ b/src/mlkit/imagelabeling/imagelabeling-common.ts @@ -1,4 +1,4 @@ -import { Property } from "tns-core-modules/ui/core/properties"; +import { Property } from "@nativescript/core"; import { MLKitCameraView } from "../mlkit-cameraview"; // TODO could combine this with 'maxResults' diff --git a/src/mlkit/imagelabeling/index.android.ts b/src/mlkit/imagelabeling/index.android.ts index b5746c62..f06e25a2 100644 --- a/src/mlkit/imagelabeling/index.android.ts +++ b/src/mlkit/imagelabeling/index.android.ts @@ -1,4 +1,4 @@ -import { ImageSource } from "tns-core-modules/image-source"; +import { ImageSource } from "@nativescript/core"; import { MLKitVisionOptions, } from "../"; import { MLKitImageLabelingOptions, MLKitImageLabelingCloudResult, MLKitImageLabelingOnDeviceResult } from "./"; import { MLKitImageLabeling as MLKitImageLabelingBase } from "./imagelabeling-common"; diff --git a/src/mlkit/imagelabeling/index.ios.ts b/src/mlkit/imagelabeling/index.ios.ts index c7a989eb..cb8c843b 100644 --- a/src/mlkit/imagelabeling/index.ios.ts +++ b/src/mlkit/imagelabeling/index.ios.ts @@ -1,4 +1,4 @@ -import { ImageSource } from "tns-core-modules/image-source"; +import { ImageSource } from "@nativescript/core"; import { MLKitVisionOptions } from "../"; import { MLKitImageLabelingCloudResult, MLKitImageLabelingOnDeviceResult, MLKitImageLabelingOptions } from "./"; import { MLKitImageLabeling as MLKitImageLabelingBase } from "./imagelabeling-common"; diff --git a/src/mlkit/index.ts b/src/mlkit/index.ts index 09da1ebd..8986f691 100644 --- a/src/mlkit/index.ts +++ b/src/mlkit/index.ts @@ -10,8 +10,7 @@ import * as naturallanguageidentification from "./naturallanguageidentification" import * as translation from "./translation"; import * as smartreply from "./smartreply"; -import { ImageSource } from "tns-core-modules/image-source"; -import { Image } from "tns-core-modules/ui/image"; +import { ImageSource, Image } from "@nativescript/core"; export interface MLKitVisionOptions { image?: Image | ImageSource; diff --git a/src/mlkit/landmarkrecognition/index.android.ts b/src/mlkit/landmarkrecognition/index.android.ts index 18cb2456..d5010a49 100644 --- a/src/mlkit/landmarkrecognition/index.android.ts +++ b/src/mlkit/landmarkrecognition/index.android.ts @@ -1,4 +1,4 @@ -import { ImageSource } from "tns-core-modules/image-source"; +import { ImageSource } from "@nativescript/core"; import { MLKitVisionOptions, } from "../"; import { MLKitLandmarkRecognitionCloudOptions, MLKitLandmarkRecognitionCloudResult } from "./index"; import { MLKitCloudModelType } from "../index"; diff --git a/src/mlkit/landmarkrecognition/index.ios.ts b/src/mlkit/landmarkrecognition/index.ios.ts index eb07916b..37d9bfc3 100644 --- a/src/mlkit/landmarkrecognition/index.ios.ts +++ b/src/mlkit/landmarkrecognition/index.ios.ts @@ -1,4 +1,4 @@ -import { ImageSource } from "tns-core-modules/image-source"; +import { ImageSource } from "@nativescript/core"; import { MLKitVisionOptions } from "../"; import { MLKitLandmarkRecognitionCloudOptions, MLKitLandmarkRecognitionCloudResult } from "./"; import { MLKitCloudModelType } from "../index"; diff --git a/src/mlkit/mlkit-cameraview-common.ts b/src/mlkit/mlkit-cameraview-common.ts index 5fc10267..168673a5 100644 --- a/src/mlkit/mlkit-cameraview-common.ts +++ b/src/mlkit/mlkit-cameraview-common.ts @@ -1,6 +1,4 @@ -import { ContentView } from "tns-core-modules/ui/content-view"; -import { Property } from "tns-core-modules/ui/core/properties"; -import { booleanConverter } from "tns-core-modules/ui/core/view-base"; +import { ContentView, Property, booleanConverter } from "@nativescript/core"; export const processEveryNthFrameProperty = new Property({ name: "processEveryNthFrame", diff --git a/src/mlkit/mlkit-cameraview.android.ts b/src/mlkit/mlkit-cameraview.android.ts index f5f8da97..f6bfa30e 100644 --- a/src/mlkit/mlkit-cameraview.android.ts +++ b/src/mlkit/mlkit-cameraview.android.ts @@ -1,5 +1,4 @@ -import * as application from "tns-core-modules/application"; -import * as utils from "tns-core-modules/utils/utils"; +import { Application, AndroidActivityRequestPermissionsEventData, AndroidApplication, Utils } from "@nativescript/core"; import { MLKitCameraView as MLKitCameraViewBase } from "./mlkit-cameraview-common"; declare const android, global: any; @@ -38,7 +37,7 @@ export abstract class MLKitCameraView extends MLKitCameraViewBase { this.surfaceView = null; if (this.camera != null) { - application.off("orientationChanged"); + Application.off("orientationChanged"); this.camera.stopPreview(); this.camera.setPreviewCallbackWithBuffer(null); @@ -67,9 +66,9 @@ export abstract class MLKitCameraView extends MLKitCameraViewBase { if (this.wasCameraPermissionGranted()) { this.initView(nativeView); } else { - const permissionCb = (args: application.AndroidActivityRequestPermissionsEventData) => { + const permissionCb = (args: AndroidActivityRequestPermissionsEventData) => { if (args.requestCode === CAMERA_PERMISSION_REQUEST_CODE) { - application.android.off(application.AndroidApplication.activityRequestPermissionsEvent, permissionCb); + Application.android.off(AndroidApplication.activityRequestPermissionsEvent, permissionCb); for (let i = 0; i < args.permissions.length; i++) { if (args.grantResults[i] === android.content.pm.PackageManager.PERMISSION_DENIED) { @@ -83,11 +82,11 @@ export abstract class MLKitCameraView extends MLKitCameraViewBase { }; // grab the permission dialog result - application.android.on(application.AndroidApplication.activityRequestPermissionsEvent, permissionCb); + Application.android.on(AndroidApplication.activityRequestPermissionsEvent, permissionCb); // invoke the permission dialog ActivityCompatClass.requestPermissions( - application.android.foregroundActivity || application.android.startActivity, + Application.android.foregroundActivity || Application.android.startActivity, [android.Manifest.permission.CAMERA], CAMERA_PERMISSION_REQUEST_CODE); } @@ -99,11 +98,11 @@ export abstract class MLKitCameraView extends MLKitCameraViewBase { initNativeView(): void { super.initNativeView(); - application.on("resume", arg => this.runCamera()); + Application.on("resume", arg => this.runCamera()); } private hasCamera(): boolean { - return !!utils.ad + return !!Utils.android .getApplicationContext() .getPackageManager() .hasSystemFeature("android.hardware.camera"); @@ -113,13 +112,13 @@ export abstract class MLKitCameraView extends MLKitCameraViewBase { let hasPermission = android.os.Build.VERSION.SDK_INT < 23; // Android M. (6.0) if (!hasPermission) { hasPermission = android.content.pm.PackageManager.PERMISSION_GRANTED === - ContentPackageName.ContextCompat.checkSelfPermission(utils.ad.getApplicationContext(), android.Manifest.permission.CAMERA); + ContentPackageName.ContextCompat.checkSelfPermission(Utils.android.getApplicationContext(), android.Manifest.permission.CAMERA); } return hasPermission; } private initView(nativeView): void { - this.surfaceView = new android.view.SurfaceView(utils.ad.getApplicationContext()); + this.surfaceView = new android.view.SurfaceView(Utils.android.getApplicationContext()); nativeView.addView(this.surfaceView); this.runCamera(); } @@ -164,8 +163,8 @@ export abstract class MLKitCameraView extends MLKitCameraViewBase { parameters.setPreviewSize(previewSize.width, previewSize.height); parameters.setPreviewFormat(android.graphics.ImageFormat.NV21); - application.off("orientationChanged"); - application.on("orientationChanged", () => { + Application.off("orientationChanged"); + Application.on("orientationChanged", () => { this.setRotation(this.camera, parameters, requestedCameraId); setTimeout(() => { this.fixStretch(previewSize); @@ -399,7 +398,7 @@ export abstract class MLKitCameraView extends MLKitCameraViewBase { } private setRotation(camera, parameters, cameraId): void { - let windowManager = (application.android.foregroundActivity || application.android.startActivity).getSystemService(android.content.Context.WINDOW_SERVICE); + let windowManager = (Application.android.foregroundActivity || Application.android.startActivity).getSystemService(android.content.Context.WINDOW_SERVICE); let degrees = 0; const deviceRotation = windowManager.getDefaultDisplay().getRotation(); switch (deviceRotation) { diff --git a/src/mlkit/mlkit-cameraview.ios.ts b/src/mlkit/mlkit-cameraview.ios.ts index 00d8a2b1..ac44a0fe 100644 --- a/src/mlkit/mlkit-cameraview.ios.ts +++ b/src/mlkit/mlkit-cameraview.ios.ts @@ -1,7 +1,5 @@ -import { ios as iosUtils } from "tns-core-modules/utils/utils"; -import * as application from "tns-core-modules/application"; +import { Utils, Application, OrientationChangedEventData } from "@nativescript/core"; import { MLKitCameraView as MLKitCameraViewBase } from "./mlkit-cameraview-common"; -import { OrientationChangedEventData } from "tns-core-modules/application"; export abstract class MLKitCameraView extends MLKitCameraViewBase { private captureSession: AVCaptureSession; @@ -20,7 +18,7 @@ export abstract class MLKitCameraView extends MLKitCameraViewBase { this.captureDevice = undefined; this.previewLayer = undefined; this.cameraView = undefined; - application.off("orientationChanged"); + Application.off("orientationChanged"); } createNativeView(): Object { @@ -71,7 +69,7 @@ export abstract class MLKitCameraView extends MLKitCameraViewBase { this.previewLayer = AVCaptureVideoPreviewLayer.layerWithSession(this.captureSession); this.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; - if (iosUtils.isLandscape()) { + if (Utils.ios.isLandscape()) { const deviceOrientation = UIDevice.currentDevice.orientation; this.previewLayer.connection.videoOrientation = deviceOrientation === UIDeviceOrientation.LandscapeLeft ? AVCaptureVideoOrientation.LandscapeRight : AVCaptureVideoOrientation.LandscapeLeft; } else { @@ -79,8 +77,8 @@ export abstract class MLKitCameraView extends MLKitCameraViewBase { } // note that when rotating back to portrait, this event fires very late.. not much we can do I think - application.off("orientationChanged"); // just making sure it was off - application.on("orientationChanged", this.rotateOnOrientationChange.bind(this)); + Application.off(Application.orientationChangedEvent); // just making sure it was off + Application.on(Application.orientationChangedEvent, this.rotateOnOrientationChange.bind(this)); setTimeout(() => { if (this.ios) { @@ -184,6 +182,7 @@ export abstract class MLKitCameraView extends MLKitCameraViewBase { } } +@NativeClass() class TNSMLKitCameraViewDelegateImpl extends NSObject implements TNSMLKitCameraViewDelegate { public static ObjCProtocols = []; private owner: WeakRef; diff --git a/src/mlkit/objectdetection/index.android.ts b/src/mlkit/objectdetection/index.android.ts index 6209a935..430b5c10 100644 --- a/src/mlkit/objectdetection/index.android.ts +++ b/src/mlkit/objectdetection/index.android.ts @@ -1,4 +1,4 @@ -import { ImageSource } from "tns-core-modules/image-source"; +import { ImageSource } from "@nativescript/core"; import { MLKitVisionOptions, } from "../"; import { MLKitScanBarcodesResultBounds } from "../barcodescanning"; import { MLKitObjectDetectionOptions, MLKitObjectDetectionResult, MLKitObjectDetectionResultItem } from "./"; diff --git a/src/mlkit/objectdetection/index.ios.ts b/src/mlkit/objectdetection/index.ios.ts index d36033b3..da877c1c 100644 --- a/src/mlkit/objectdetection/index.ios.ts +++ b/src/mlkit/objectdetection/index.ios.ts @@ -1,5 +1,4 @@ -import { ImageSource } from "tns-core-modules/image-source"; -import { ios as iosUtils } from "tns-core-modules/utils/utils"; +import { ImageSource, Utils } from "@nativescript/core"; import { MLKitVisionOptions } from "../"; import { MLKitObjectDetectionOptions, MLKitObjectDetectionResult, MLKitObjectDetectionResultItem } from "./"; import { MLKitObjectDetection as MLKitObjectDetectionBase, ObjectDetectionCategory } from "./objectdetection-common"; @@ -94,7 +93,7 @@ function getMLKitObjectDetectionResultItem(obj: FIRVisionObject, image: UIImage) const origWidth = width; const origImageWidth = imageWidth; - if (iosUtils.isLandscape()) { + if (Utils.ios.isLandscape()) { if (UIDevice.currentDevice.orientation === UIDeviceOrientation.LandscapeRight) { // the image is rotated 180 degrees x = image.size.width - (width + x); diff --git a/src/mlkit/objectdetection/objectdetection-common.ts b/src/mlkit/objectdetection/objectdetection-common.ts index b4d44827..d3fbc76c 100644 --- a/src/mlkit/objectdetection/objectdetection-common.ts +++ b/src/mlkit/objectdetection/objectdetection-common.ts @@ -1,5 +1,4 @@ -import { Property } from "tns-core-modules/ui/core/properties"; -import { booleanConverter } from "tns-core-modules/ui/core/view-base"; +import { Property, booleanConverter } from "@nativescript/core"; import { MLKitCameraView } from "../mlkit-cameraview"; export enum ObjectDetectionCategory { diff --git a/src/mlkit/textrecognition/index.android.ts b/src/mlkit/textrecognition/index.android.ts index 6f367c0f..fbf3c473 100644 --- a/src/mlkit/textrecognition/index.android.ts +++ b/src/mlkit/textrecognition/index.android.ts @@ -1,4 +1,4 @@ -import { ImageSource } from "tns-core-modules/image-source"; +import { ImageSource } from "@nativescript/core"; import { MLKitVisionOptions, } from "../"; import { MLKitRecognizeTextOnDeviceOptions, MLKitRecognizeTextResult } from "./"; import { MLKitTextRecognition as MLKitTextRecognitionBase } from "./textrecognition-common"; diff --git a/src/mlkit/textrecognition/index.ios.ts b/src/mlkit/textrecognition/index.ios.ts index 8b9e0ae1..8e0bf83f 100644 --- a/src/mlkit/textrecognition/index.ios.ts +++ b/src/mlkit/textrecognition/index.ios.ts @@ -1,4 +1,4 @@ -import { ImageSource } from "tns-core-modules/image-source"; +import { ImageSource } from "@nativescript/core"; import { MLKitVisionOptions } from "../"; import { MLKitRecognizeTextCloudOptions, MLKitRecognizeTextOnDeviceOptions, MLKitRecognizeTextResult } from "./"; import { MLKitTextRecognition as MLKitTextRecognitionBase } from "./textrecognition-common"; diff --git a/src/mlkit/textrecognition/textrecognition-common.ts b/src/mlkit/textrecognition/textrecognition-common.ts index 29d845bd..60c90d89 100644 --- a/src/mlkit/textrecognition/textrecognition-common.ts +++ b/src/mlkit/textrecognition/textrecognition-common.ts @@ -1,5 +1,4 @@ -import { booleanConverter } from "tns-core-modules/ui/core/view-base"; -import { Property } from "tns-core-modules/ui/core/properties"; +import { Property, booleanConverter } from "@nativescript/core"; import { MLKitCameraView } from "../mlkit-cameraview"; export const reportDuplicatesProperty = new Property({ diff --git a/src/package.json b/src/package.json index 65b39c5e..964344aa 100644 --- a/src/package.json +++ b/src/package.json @@ -1,6 +1,6 @@ { - "name": "nativescript-plugin-firebase", - "version": "10.6.0", + "name": "@nativescript/firebase", + "version": "11.1.0", "description": "Fire. Base. Firebase!", "main": "firebase", "typings": "index.d.ts", @@ -32,11 +32,12 @@ "typingsproject": "demo-ng" }, "scripts": { + "clean": "npx rimraf node_modules package-lock.json && npm i --ignore-scripts && ts-patch install", "postinstall": "node postinstall-hooks.js && node scripts/postinstall.js", "preuninstall": "node preuninstall-hooks.js", "setup": "node scripts/postinstall.js setup", "config": "node scripts/postinstall.js config", - "tsc": "tsc -skipLibCheck", + "tsc": "ts-patch install && tsc -skipLibCheck", "plugin.tscwatch": "npm run tsc -- -w", "package": "cd ../publish && ./pack.sh", "demo.ios": "npm run preparedemo && cd ../demo && tns run ios", @@ -134,18 +135,20 @@ "homepage": "https://github.com/eddyverbruggen/nativescript-plugin-firebase", "readmeFilename": "README.md", "dependencies": { - "fs-extra": "~2.1.0", - "nativescript-hook": "~0.2.5", - "nativescript-shared-notification-delegate": "~1.0.0", + "fs-extra": "~9.0.1", + "@nativescript/hook": "~2.0.0", + "@nativescript/shared-notification-delegate": "~1.0.0", "prompt-lite": "~0.1.1", "xcode": "~0.9.3", - "semver": "~5.7.1" + "semver": "~7.3.2" }, "devDependencies": { - "rimraf": "~2.7.1", - "tns-core-modules": "~6.3.2", - "tns-platform-declarations": "~6.3.2", - "tslint": "~5.20.1", - "typescript": "~3.4.5" + "rimraf": "~3.0.2", + "@nativescript/core": "~7.0.0", + "@nativescript/types": "~7.0.0", + "@nativescript/webpack": "~3.0.0", + "tslint": "~6.1.3", + "typescript": "~4.0.0", + "ts-patch": "^1.3.0" } } diff --git a/src/postinstall-hooks.js b/src/postinstall-hooks.js index 5ba5ddce..7aafb4e4 100644 --- a/src/postinstall-hooks.js +++ b/src/postinstall-hooks.js @@ -1 +1 @@ -require('nativescript-hook')(__dirname).postinstall(); +require('@nativescript/hook')(__dirname).postinstall(); diff --git a/src/preuninstall-hooks.js b/src/preuninstall-hooks.js index b72ac69f..3c292e1e 100644 --- a/src/preuninstall-hooks.js +++ b/src/preuninstall-hooks.js @@ -1 +1 @@ -require('nativescript-hook')(__dirname).preuninstall(); +require('@nativescript/hook')(__dirname).preuninstall(); diff --git a/src/references.d.ts b/src/references.d.ts index 13f3337b..5a69dde2 100644 --- a/src/references.d.ts +++ b/src/references.d.ts @@ -1,5 +1,5 @@ -/// -/// +/// +/// /// /// diff --git a/src/storage/storage.android.ts b/src/storage/storage.android.ts index d1161b45..414ca924 100644 --- a/src/storage/storage.android.ts +++ b/src/storage/storage.android.ts @@ -1,4 +1,4 @@ -import { File } from "tns-core-modules/file-system"; +import { File } from "@nativescript/core"; import { firebase } from "../firebase-common"; import { DeleteFileOptions, DownloadFileOptions, GetDownloadUrlOptions, ListOptions, Reference, UploadFileOptions, UploadFileResult } from "./storage"; import { ListResult as ListResultBase } from "./storage-common"; diff --git a/src/tsconfig.json b/src/tsconfig.json index 98a7191e..04973119 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -1,38 +1,34 @@ { "compilerOptions": { - "target": "es5", - "module": "commonjs", - "removeComments": true, - "declaration": true, - "noLib": false, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "skipLibCheck": true, - "lib": [ - "es6", - "dom" - ], - "sourceMap": false, - "pretty": true, - "allowUnreachableCode": false, - "allowUnusedLabels": false, - "noEmitHelpers": true, - "noEmitOnError": false, - "noImplicitAny": false, - "noImplicitReturns": true, - "noImplicitUseStrict": false, - "noFallthroughCasesInSwitch": true, - "typeRoots": [ - "./node_modules/@types", - "./node_modules" - ], - "types": [ - ] + "rootDir": ".", + "target": "ES2017", + "module": "esnext", + "moduleResolution": "node", + "sourceMap": true, + "declaration": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "noEmitOnError": false, + "noEmitHelpers": true, + "diagnostics": true, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "pretty": true, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "noImplicitAny": false, + "noImplicitReturns": true, + "noImplicitUseStrict": false, + "noFallthroughCasesInSwitch": true, + "lib": ["es2017", "dom"], + "plugins": [ + { "transform": "@nativescript/webpack/transformers/ns-transform-native-classes", "type": "raw" } + ] }, "exclude": [ "demo", "scripts", "node_modules" - ], - "compileOnSave": false -} + ] +} \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts index 2fe48663..d25fc79d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -3,7 +3,7 @@ */ import { firebase } from "./firebase-common"; -import { getClass } from "tns-core-modules/utils/types"; +import { Utils as coreUtils } from "@nativescript/core"; export class Utils { public invokeOnRunLoop = (() => { @@ -52,7 +52,7 @@ export class Utils { } private getValueForClass(val) { - switch (getClass(val)) { + switch (coreUtils.getClass(val)) { case 'NSArray': case 'NSMutableArray': return this.toJsObject(val); @@ -80,7 +80,7 @@ export class Utils { (val).longitude ); default: - console.log("Please report this at https://github.com/EddyVerbruggen/nativescript-plugin-firebase/issues: iOS toJsObject is missing a converter for class '" + getClass(val) + "'. Casting to String as a fallback."); + console.log("Please report this at https://github.com/EddyVerbruggen/nativescript-plugin-firebase/issues: iOS toJsObject is missing a converter for class '" + coreUtils.getClass(val) + "'. Casting to String as a fallback."); return String(val); } }