├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── plugin.xml ├── scripts └── sync-plugin-version.js ├── src ├── android │ ├── .gitignore │ ├── com │ │ └── blakgeek │ │ │ └── cordova │ │ │ └── plugin │ │ │ └── FirebaseAuthGooglePlugin.java │ └── plugin.gradle └── ios │ ├── AppDelegate+FirebaseAuthGooglePlugin.h │ ├── AppDelegate+FirebaseAuthGooglePlugin.m │ ├── FirebaseAuthGooglePlugin.h │ └── FirebaseAuthGooglePlugin.m └── www └── firebaseAuthGooglePlugin.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | .idea/ 3 | *.iml 4 | node_modules/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cordova-plugin-firebase-auth-google 2 | A super awesome plugin that let's you login into you app Firebase and a Google account. 3 | 4 | ## How do I install it? 5 | 6 | If you're like me and using [Cordova CLI](http://cordova.apache.org/): 7 | ``` 8 | cordova plugin add cordova-plugin-firebase-auth-google 9 | ``` 10 | 11 | or 12 | 13 | ``` 14 | phonegap local plugin add cordova-plugin-app-name --variable APP_NAME="Look I Got Spaces and Stuff!" 15 | ``` 16 | 17 | ## How do I use it? 18 | 1. Download the google-services.json and/or GoogleService-Info.plist for you application from the Firebase console. 19 | 1. Copy the files from previous step to root of your project. If you don't do this plugin's hook won't be able to copy 20 | them to the appropriate locations and bad things will happen at runtime. So make you do this. 21 | 1. Now you're ready to write some code. 22 | 23 | ```javascript 24 | const fbAuth = new FirebaseAuth({ 25 | allowDomains: ['blakgeek.com'] // optionally restrict the domains that can used to log into the app. 26 | }) 27 | ```` 28 | 29 | ## How do I sign in 30 | ```javascript 31 | // on succesful sign in this event will be fired on the window (fancy name huh?) 32 | window.addEventListener('signinsuccess', function (event) { 33 | 34 | console.log('Wassup?'); 35 | // the detail property of the event will contain the information about the user 36 | // ("token", "id", "name", "email", "id", "photoUrl") 37 | console.dir(event.detail); 38 | }, false); 39 | 40 | // on an error during sign in this even will raised 41 | window.addEventListener('signinfailure', function (event) { 42 | 43 | console.error('Oh snap'); 44 | // the detail property will contain the error details 45 | // (code, message and optionally the domain) 46 | // domain is included if the domain of user's email was not in the allowDomain list 47 | console.error(event.detail) 48 | }, false); 49 | 50 | // sign in by showing a UI 51 | fbAuth.signIn(); 52 | 53 | // attempt to sign in without a UI (silently) 54 | fbAuth.signIn(true); 55 | ``` 56 | 57 | ## How do I sign out? 58 | ```javascript 59 | window.addEventListener('signoutsuccess', function (event) { 60 | 61 | console.log('Holla!') 62 | }, false); 63 | fbAuth.signOut(); 64 | ``` 65 | 66 | ## How do I get the user's token? 67 | ```javascript 68 | fbAuth.getToken().then(token => { 69 | console.log(token); 70 | }).catch(err => { 71 | console.error(err); 72 | }); 73 | // or old school 74 | fbAuth.getToken(token => { 75 | console.log(token); 76 | }, err => { 77 | console.error(err); 78 | }); 79 | ``` 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cordova-plugin-firebase-auth-google", 3 | "version": "1.3.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "abbrev": { 8 | "version": "1.1.1", 9 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 10 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", 11 | "dev": true 12 | }, 13 | "ansi-regex": { 14 | "version": "2.1.1", 15 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 16 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 17 | "dev": true 18 | }, 19 | "aproba": { 20 | "version": "1.2.0", 21 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", 22 | "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", 23 | "dev": true 24 | }, 25 | "are-we-there-yet": { 26 | "version": "1.1.5", 27 | "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", 28 | "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", 29 | "dev": true, 30 | "requires": { 31 | "delegates": "^1.0.0", 32 | "readable-stream": "^2.0.6" 33 | } 34 | }, 35 | "balanced-match": { 36 | "version": "1.0.0", 37 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 38 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 39 | }, 40 | "base64-js": { 41 | "version": "0.0.8", 42 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", 43 | "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=" 44 | }, 45 | "bindings": { 46 | "version": "1.3.0", 47 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", 48 | "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==", 49 | "dev": true 50 | }, 51 | "bplist-creator": { 52 | "version": "0.0.4", 53 | "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.4.tgz", 54 | "integrity": "sha1-SsBJZ4LhJ6hcHSAmpPXrIqev+ZE=", 55 | "requires": { 56 | "stream-buffers": "~0.2.3" 57 | } 58 | }, 59 | "bplist-parser": { 60 | "version": "0.0.6", 61 | "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.0.6.tgz", 62 | "integrity": "sha1-ONo0cYF9+dRKs4kuJ3B7u9daEbk=" 63 | }, 64 | "brace-expansion": { 65 | "version": "1.1.11", 66 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 67 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 68 | "requires": { 69 | "balanced-match": "^1.0.0", 70 | "concat-map": "0.0.1" 71 | } 72 | }, 73 | "chownr": { 74 | "version": "1.0.1", 75 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", 76 | "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", 77 | "dev": true 78 | }, 79 | "code-point-at": { 80 | "version": "1.1.0", 81 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 82 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", 83 | "dev": true 84 | }, 85 | "concat-map": { 86 | "version": "0.0.1", 87 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 88 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 89 | }, 90 | "console-control-strings": { 91 | "version": "1.1.0", 92 | "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", 93 | "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", 94 | "dev": true 95 | }, 96 | "core-util-is": { 97 | "version": "1.0.2", 98 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 99 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 100 | "dev": true 101 | }, 102 | "debug": { 103 | "version": "2.6.9", 104 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 105 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 106 | "dev": true, 107 | "requires": { 108 | "ms": "2.0.0" 109 | } 110 | }, 111 | "deep-extend": { 112 | "version": "0.6.0", 113 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 114 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", 115 | "dev": true 116 | }, 117 | "delegates": { 118 | "version": "1.0.0", 119 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", 120 | "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", 121 | "dev": true 122 | }, 123 | "detect-libc": { 124 | "version": "1.0.3", 125 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", 126 | "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", 127 | "dev": true 128 | }, 129 | "elementtree": { 130 | "version": "0.1.7", 131 | "resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.7.tgz", 132 | "integrity": "sha1-mskb5uUvtuYkTE5UpKw+2K6OKcA=", 133 | "requires": { 134 | "sax": "1.1.4" 135 | } 136 | }, 137 | "fs-minipass": { 138 | "version": "1.2.5", 139 | "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", 140 | "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", 141 | "dev": true, 142 | "requires": { 143 | "minipass": "^2.2.1" 144 | } 145 | }, 146 | "fs.realpath": { 147 | "version": "1.0.0", 148 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 149 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 150 | }, 151 | "gauge": { 152 | "version": "2.7.4", 153 | "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", 154 | "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", 155 | "dev": true, 156 | "requires": { 157 | "aproba": "^1.0.3", 158 | "console-control-strings": "^1.0.0", 159 | "has-unicode": "^2.0.0", 160 | "object-assign": "^4.1.0", 161 | "signal-exit": "^3.0.0", 162 | "string-width": "^1.0.1", 163 | "strip-ansi": "^3.0.1", 164 | "wide-align": "^1.1.0" 165 | } 166 | }, 167 | "glob": { 168 | "version": "7.1.2", 169 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 170 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 171 | "requires": { 172 | "fs.realpath": "^1.0.0", 173 | "inflight": "^1.0.4", 174 | "inherits": "2", 175 | "minimatch": "^3.0.4", 176 | "once": "^1.3.0", 177 | "path-is-absolute": "^1.0.0" 178 | } 179 | }, 180 | "has-unicode": { 181 | "version": "2.0.1", 182 | "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", 183 | "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", 184 | "dev": true 185 | }, 186 | "iconv-lite": { 187 | "version": "0.4.23", 188 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", 189 | "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", 190 | "dev": true, 191 | "requires": { 192 | "safer-buffer": ">= 2.1.2 < 3" 193 | } 194 | }, 195 | "ignore-walk": { 196 | "version": "3.0.1", 197 | "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", 198 | "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", 199 | "dev": true, 200 | "requires": { 201 | "minimatch": "^3.0.4" 202 | } 203 | }, 204 | "inflight": { 205 | "version": "1.0.6", 206 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 207 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 208 | "requires": { 209 | "once": "^1.3.0", 210 | "wrappy": "1" 211 | } 212 | }, 213 | "inherits": { 214 | "version": "2.0.3", 215 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 216 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 217 | }, 218 | "ini": { 219 | "version": "1.3.5", 220 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", 221 | "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", 222 | "dev": true 223 | }, 224 | "interpret": { 225 | "version": "1.1.0", 226 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", 227 | "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=" 228 | }, 229 | "is-fullwidth-code-point": { 230 | "version": "1.0.0", 231 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 232 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 233 | "dev": true, 234 | "requires": { 235 | "number-is-nan": "^1.0.0" 236 | } 237 | }, 238 | "isarray": { 239 | "version": "1.0.0", 240 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 241 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 242 | "dev": true 243 | }, 244 | "libxmljs": { 245 | "version": "0.18.8", 246 | "resolved": "https://registry.npmjs.org/libxmljs/-/libxmljs-0.18.8.tgz", 247 | "integrity": "sha1-sKB1EqASkLYkBgDWwrwzo8cJdtY=", 248 | "dev": true, 249 | "requires": { 250 | "bindings": "^1.3.0", 251 | "nan": "~2.10.0", 252 | "node-pre-gyp": "^0.9.1" 253 | } 254 | }, 255 | "lodash": { 256 | "version": "3.10.1", 257 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", 258 | "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" 259 | }, 260 | "minimatch": { 261 | "version": "3.0.4", 262 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 263 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 264 | "requires": { 265 | "brace-expansion": "^1.1.7" 266 | } 267 | }, 268 | "minimist": { 269 | "version": "0.0.8", 270 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 271 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 272 | "dev": true 273 | }, 274 | "minipass": { 275 | "version": "2.3.3", 276 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.3.tgz", 277 | "integrity": "sha512-/jAn9/tEX4gnpyRATxgHEOV6xbcyxgT7iUnxo9Y3+OB0zX00TgKIv/2FZCf5brBbICcwbLqVv2ImjvWWrQMSYw==", 278 | "dev": true, 279 | "requires": { 280 | "safe-buffer": "^5.1.2", 281 | "yallist": "^3.0.0" 282 | } 283 | }, 284 | "minizlib": { 285 | "version": "1.1.0", 286 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz", 287 | "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", 288 | "dev": true, 289 | "requires": { 290 | "minipass": "^2.2.1" 291 | } 292 | }, 293 | "mkdirp": { 294 | "version": "0.5.1", 295 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 296 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 297 | "dev": true, 298 | "requires": { 299 | "minimist": "0.0.8" 300 | } 301 | }, 302 | "ms": { 303 | "version": "2.0.0", 304 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 305 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 306 | "dev": true 307 | }, 308 | "nan": { 309 | "version": "2.10.0", 310 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", 311 | "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", 312 | "dev": true 313 | }, 314 | "needle": { 315 | "version": "2.2.1", 316 | "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.1.tgz", 317 | "integrity": "sha512-t/ZswCM9JTWjAdXS9VpvqhI2Ct2sL2MdY4fUXqGJaGBk13ge99ObqRksRTbBE56K+wxUXwwfZYOuZHifFW9q+Q==", 318 | "dev": true, 319 | "requires": { 320 | "debug": "^2.1.2", 321 | "iconv-lite": "^0.4.4", 322 | "sax": "^1.2.4" 323 | }, 324 | "dependencies": { 325 | "sax": { 326 | "version": "1.2.4", 327 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", 328 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", 329 | "dev": true 330 | } 331 | } 332 | }, 333 | "node-pre-gyp": { 334 | "version": "0.9.1", 335 | "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.9.1.tgz", 336 | "integrity": "sha1-8RwHUW3ZL4cZnbx+GDjqt81WyeA=", 337 | "dev": true, 338 | "requires": { 339 | "detect-libc": "^1.0.2", 340 | "mkdirp": "^0.5.1", 341 | "needle": "^2.2.0", 342 | "nopt": "^4.0.1", 343 | "npm-packlist": "^1.1.6", 344 | "npmlog": "^4.0.2", 345 | "rc": "^1.1.7", 346 | "rimraf": "^2.6.1", 347 | "semver": "^5.3.0", 348 | "tar": "^4" 349 | } 350 | }, 351 | "node-uuid": { 352 | "version": "1.4.7", 353 | "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz", 354 | "integrity": "sha1-baWhdmjEs91ZYjvaEc9/pMH2Cm8=" 355 | }, 356 | "nopt": { 357 | "version": "4.0.1", 358 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", 359 | "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", 360 | "dev": true, 361 | "requires": { 362 | "abbrev": "1", 363 | "osenv": "^0.1.4" 364 | } 365 | }, 366 | "npm-bundled": { 367 | "version": "1.0.3", 368 | "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.3.tgz", 369 | "integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==", 370 | "dev": true 371 | }, 372 | "npm-packlist": { 373 | "version": "1.1.10", 374 | "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.10.tgz", 375 | "integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==", 376 | "dev": true, 377 | "requires": { 378 | "ignore-walk": "^3.0.1", 379 | "npm-bundled": "^1.0.1" 380 | } 381 | }, 382 | "npmlog": { 383 | "version": "4.1.2", 384 | "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", 385 | "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", 386 | "dev": true, 387 | "requires": { 388 | "are-we-there-yet": "~1.1.2", 389 | "console-control-strings": "~1.1.0", 390 | "gauge": "~2.7.3", 391 | "set-blocking": "~2.0.0" 392 | } 393 | }, 394 | "number-is-nan": { 395 | "version": "1.0.1", 396 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 397 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", 398 | "dev": true 399 | }, 400 | "object-assign": { 401 | "version": "4.1.1", 402 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 403 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 404 | "dev": true 405 | }, 406 | "once": { 407 | "version": "1.4.0", 408 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 409 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 410 | "requires": { 411 | "wrappy": "1" 412 | } 413 | }, 414 | "os-homedir": { 415 | "version": "1.0.2", 416 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", 417 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", 418 | "dev": true 419 | }, 420 | "os-tmpdir": { 421 | "version": "1.0.2", 422 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 423 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 424 | "dev": true 425 | }, 426 | "osenv": { 427 | "version": "0.1.5", 428 | "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", 429 | "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", 430 | "dev": true, 431 | "requires": { 432 | "os-homedir": "^1.0.0", 433 | "os-tmpdir": "^1.0.0" 434 | } 435 | }, 436 | "path-is-absolute": { 437 | "version": "1.0.1", 438 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 439 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 440 | }, 441 | "path-parse": { 442 | "version": "1.0.5", 443 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", 444 | "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" 445 | }, 446 | "pegjs": { 447 | "version": "0.9.0", 448 | "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.9.0.tgz", 449 | "integrity": "sha1-9q76LjzlYWkgjlIXnf5B+JFBo2k=" 450 | }, 451 | "plist": { 452 | "version": "1.2.0", 453 | "resolved": "https://registry.npmjs.org/plist/-/plist-1.2.0.tgz", 454 | "integrity": "sha1-CEtQk93JJQbiWfh0uNmxr7jHlZM=", 455 | "requires": { 456 | "base64-js": "0.0.8", 457 | "util-deprecate": "1.0.2", 458 | "xmlbuilder": "4.0.0", 459 | "xmldom": "0.1.x" 460 | } 461 | }, 462 | "process-nextick-args": { 463 | "version": "2.0.0", 464 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 465 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", 466 | "dev": true 467 | }, 468 | "rc": { 469 | "version": "1.2.8", 470 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", 471 | "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", 472 | "dev": true, 473 | "requires": { 474 | "deep-extend": "^0.6.0", 475 | "ini": "~1.3.0", 476 | "minimist": "^1.2.0", 477 | "strip-json-comments": "~2.0.1" 478 | }, 479 | "dependencies": { 480 | "minimist": { 481 | "version": "1.2.0", 482 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 483 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", 484 | "dev": true 485 | } 486 | } 487 | }, 488 | "readable-stream": { 489 | "version": "2.3.6", 490 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 491 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 492 | "dev": true, 493 | "requires": { 494 | "core-util-is": "~1.0.0", 495 | "inherits": "~2.0.3", 496 | "isarray": "~1.0.0", 497 | "process-nextick-args": "~2.0.0", 498 | "safe-buffer": "~5.1.1", 499 | "string_decoder": "~1.1.1", 500 | "util-deprecate": "~1.0.1" 501 | } 502 | }, 503 | "rechoir": { 504 | "version": "0.6.2", 505 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", 506 | "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", 507 | "requires": { 508 | "resolve": "^1.1.6" 509 | } 510 | }, 511 | "resolve": { 512 | "version": "1.7.1", 513 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", 514 | "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", 515 | "requires": { 516 | "path-parse": "^1.0.5" 517 | } 518 | }, 519 | "rimraf": { 520 | "version": "2.6.2", 521 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", 522 | "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", 523 | "dev": true, 524 | "requires": { 525 | "glob": "^7.0.5" 526 | } 527 | }, 528 | "safe-buffer": { 529 | "version": "5.1.2", 530 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 531 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 532 | "dev": true 533 | }, 534 | "safer-buffer": { 535 | "version": "2.1.2", 536 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 537 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 538 | "dev": true 539 | }, 540 | "sax": { 541 | "version": "1.1.4", 542 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz", 543 | "integrity": "sha1-dLbTPJrh4AFRDxeakRaFiPGu2qk=" 544 | }, 545 | "semver": { 546 | "version": "5.5.0", 547 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", 548 | "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", 549 | "dev": true 550 | }, 551 | "set-blocking": { 552 | "version": "2.0.0", 553 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 554 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", 555 | "dev": true 556 | }, 557 | "shelljs": { 558 | "version": "0.7.8", 559 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", 560 | "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", 561 | "requires": { 562 | "glob": "^7.0.0", 563 | "interpret": "^1.0.0", 564 | "rechoir": "^0.6.2" 565 | } 566 | }, 567 | "signal-exit": { 568 | "version": "3.0.2", 569 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 570 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 571 | "dev": true 572 | }, 573 | "simple-plist": { 574 | "version": "0.1.4", 575 | "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-0.1.4.tgz", 576 | "integrity": "sha1-EOtRtH4zxVbrjsRtXuZNZOcX210=", 577 | "requires": { 578 | "bplist-creator": "0.0.4", 579 | "bplist-parser": "0.0.6", 580 | "plist": "1.2.0" 581 | } 582 | }, 583 | "stream-buffers": { 584 | "version": "0.2.6", 585 | "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-0.2.6.tgz", 586 | "integrity": "sha1-GBwI1bs2kARfaUAbmuanoM8zE/w=" 587 | }, 588 | "string-width": { 589 | "version": "1.0.2", 590 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 591 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 592 | "dev": true, 593 | "requires": { 594 | "code-point-at": "^1.0.0", 595 | "is-fullwidth-code-point": "^1.0.0", 596 | "strip-ansi": "^3.0.0" 597 | } 598 | }, 599 | "string_decoder": { 600 | "version": "1.1.1", 601 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 602 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 603 | "dev": true, 604 | "requires": { 605 | "safe-buffer": "~5.1.0" 606 | } 607 | }, 608 | "strip-ansi": { 609 | "version": "3.0.1", 610 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 611 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 612 | "dev": true, 613 | "requires": { 614 | "ansi-regex": "^2.0.0" 615 | } 616 | }, 617 | "strip-json-comments": { 618 | "version": "2.0.1", 619 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 620 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 621 | "dev": true 622 | }, 623 | "tar": { 624 | "version": "4.4.4", 625 | "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.4.tgz", 626 | "integrity": "sha512-mq9ixIYfNF9SK0IS/h2HKMu8Q2iaCuhDDsZhdEag/FHv8fOaYld4vN7ouMgcSSt5WKZzPs8atclTcJm36OTh4w==", 627 | "dev": true, 628 | "requires": { 629 | "chownr": "^1.0.1", 630 | "fs-minipass": "^1.2.5", 631 | "minipass": "^2.3.3", 632 | "minizlib": "^1.1.0", 633 | "mkdirp": "^0.5.0", 634 | "safe-buffer": "^5.1.2", 635 | "yallist": "^3.0.2" 636 | } 637 | }, 638 | "util-deprecate": { 639 | "version": "1.0.2", 640 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 641 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 642 | }, 643 | "wide-align": { 644 | "version": "1.1.3", 645 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 646 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 647 | "dev": true, 648 | "requires": { 649 | "string-width": "^1.0.2 || 2" 650 | } 651 | }, 652 | "wrappy": { 653 | "version": "1.0.2", 654 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 655 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 656 | }, 657 | "xcode": { 658 | "version": "0.8.9", 659 | "resolved": "https://registry.npmjs.org/xcode/-/xcode-0.8.9.tgz", 660 | "integrity": "sha1-7Gdl9w6dzMzJ9umlubTn6BS0zzU=", 661 | "requires": { 662 | "node-uuid": "1.4.7", 663 | "pegjs": "0.9.0", 664 | "simple-plist": "0.1.4" 665 | } 666 | }, 667 | "xml2js": { 668 | "version": "0.4.19", 669 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", 670 | "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", 671 | "requires": { 672 | "sax": ">=0.6.0", 673 | "xmlbuilder": "~9.0.1" 674 | }, 675 | "dependencies": { 676 | "xmlbuilder": { 677 | "version": "9.0.7", 678 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", 679 | "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" 680 | } 681 | } 682 | }, 683 | "xmlbuilder": { 684 | "version": "4.0.0", 685 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.0.0.tgz", 686 | "integrity": "sha1-mLj2UcowqmJANvEn0RzGbce5B6M=", 687 | "requires": { 688 | "lodash": "^3.5.0" 689 | } 690 | }, 691 | "xmldom": { 692 | "version": "0.1.27", 693 | "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", 694 | "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" 695 | }, 696 | "yallist": { 697 | "version": "3.0.2", 698 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", 699 | "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", 700 | "dev": true 701 | } 702 | } 703 | } 704 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cordova-plugin-firebase-auth-google", 3 | "version": "1.3.1", 4 | "description": "Adds support for Firebase authentication.", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/blakgeek/cordova-plugin-firebase-auth-google.git" 8 | }, 9 | "keywords": [ 10 | "ecosystem:cordova", 11 | "cordova-android", 12 | "cordova-ios", 13 | "firebase", 14 | "authentication", 15 | "auth" 16 | ], 17 | "author": "Carlos \"blakgeek\" Lawton", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/blakgeek/cordova-plugin-firebase-auth-google/issues" 21 | }, 22 | "homepage": "https://github.com/blakgeek/cordova-plugin-firebase-auth-google", 23 | "dependencies": { 24 | "elementtree": "^0.1.6", 25 | "plist": "^1.2.0", 26 | "shelljs": "^0.7.2", 27 | "xcode": "^0.8.9", 28 | "xml2js": "^0.4.17" 29 | }, 30 | "scripts": { 31 | "postversion": "node scripts/sync-plugin-version.js; git add plugin.xml; git commit plugin.xml -m \"v${npm_package_version}\"" 32 | }, 33 | "devDependencies": { 34 | "libxmljs": "^0.18.4" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Firebase Authentication 4 | Adds support for Firebase Authenication to your Cordova/PhoneGap apps. 5 | Apache 2.0 6 | firebase,cordova,authentication 7 | Carlos "blakgeek" Lawton 8 | https://github.com/blakgeek/cordova-plugin-firebase-auth-google.git 9 | https://github.com/blakgeek/cordova-plugin-firebase-auth-google/issues 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /scripts/sync-plugin-version.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var libxml = require('libxmljs'); 3 | var version = process.env.npm_package_version; 4 | var content = fs.readFileSync('plugin.xml'); 5 | var xml = libxml.parseXmlString(content); 6 | xml.get('/p:plugin', { 7 | 'p': 'http://apache.org/cordova/ns/plugins/1.0' 8 | }).attr({ 9 | 'version': version 10 | }); 11 | 12 | fs.writeFileSync('plugin.xml', xml.toString()); 13 | -------------------------------------------------------------------------------- /src/android/.gitignore: -------------------------------------------------------------------------------- 1 | !*.jar -------------------------------------------------------------------------------- /src/android/com/blakgeek/cordova/plugin/FirebaseAuthGooglePlugin.java: -------------------------------------------------------------------------------- 1 | package com.blakgeek.cordova.plugin; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.support.annotation.NonNull; 6 | import com.google.android.gms.auth.api.Auth; 7 | import com.google.android.gms.auth.api.signin.GoogleSignInAccount; 8 | import com.google.android.gms.auth.api.signin.GoogleSignInOptions; 9 | import com.google.android.gms.auth.api.signin.GoogleSignInResult; 10 | import com.google.android.gms.common.ConnectionResult; 11 | import com.google.android.gms.common.GoogleApiAvailability; 12 | import com.google.android.gms.common.GooglePlayServicesUtil; 13 | import com.google.android.gms.common.api.CommonStatusCodes; 14 | import com.google.android.gms.common.api.GoogleApiClient; 15 | import com.google.android.gms.common.api.OptionalPendingResult; 16 | import com.google.android.gms.common.api.ResultCallback; 17 | import com.google.android.gms.common.api.Status; 18 | import com.google.android.gms.tasks.OnCompleteListener; 19 | import com.google.android.gms.tasks.Task; 20 | import com.google.firebase.auth.*; 21 | import org.apache.cordova.CallbackContext; 22 | import org.apache.cordova.CordovaPlugin; 23 | import org.apache.cordova.PluginResult; 24 | import org.json.JSONArray; 25 | import org.json.JSONException; 26 | import org.json.JSONObject; 27 | 28 | import java.util.ArrayList; 29 | import java.util.List; 30 | 31 | public class FirebaseAuthGooglePlugin extends CordovaPlugin implements OnCompleteListener, FirebaseAuth.AuthStateListener, ResultCallback { 32 | 33 | private static final int RC_SIGN_IN = 9001; 34 | private GoogleApiClient googleApiClient; 35 | private CallbackContext eventContext; 36 | private FirebaseAuth firebaseAuth; 37 | private List allowedDomains = new ArrayList<>(); 38 | private String currentToken; 39 | 40 | @Override 41 | protected void pluginInitialize() { 42 | 43 | 44 | Context context = this.cordova.getActivity().getApplicationContext(); 45 | String defaultClientId = getDefaultClientId(context); 46 | GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 47 | .requestIdToken(defaultClientId) 48 | .requestEmail() 49 | .requestProfile() 50 | .build(); 51 | 52 | int googlePlayAvailabilityStatus = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable( context); 53 | if(googlePlayAvailabilityStatus == ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED){ 54 | raiseEvent("googlePlayServiceUpdateRequired"); 55 | } 56 | 57 | googleApiClient = new GoogleApiClient.Builder(context) 58 | .addApi(Auth.GOOGLE_SIGN_IN_API, gso) 59 | .build(); 60 | googleApiClient.connect(); 61 | firebaseAuth = FirebaseAuth.getInstance(); 62 | firebaseAuth.addAuthStateListener(this); 63 | } 64 | 65 | private String getDefaultClientId(Context context) { 66 | 67 | String packageName = context.getPackageName(); 68 | int id = context.getResources().getIdentifier("default_web_client_id", "string", packageName); 69 | return context.getString(id); 70 | } 71 | 72 | @Override 73 | public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { 74 | switch (action) { 75 | case "initialize": 76 | return initialize(args, callbackContext); 77 | case "getToken": 78 | return getToken(callbackContext); 79 | case "signIn": 80 | return signIn(args.getBoolean(0)); 81 | case "signOut": 82 | return signOut(); 83 | default: 84 | return false; 85 | } 86 | } 87 | 88 | 89 | private boolean getToken(final CallbackContext callbackContext) { 90 | 91 | FirebaseUser user = firebaseAuth.getCurrentUser(); 92 | 93 | if (user != null) { 94 | user.getIdToken(false).addOnCompleteListener(new OnCompleteListener() { 95 | @Override 96 | public void onComplete(@NonNull Task task) { 97 | 98 | callbackContext.success(task.getResult().getToken()); 99 | } 100 | }); 101 | } else if (currentToken != null) { 102 | callbackContext.error("no_user_found"); 103 | } 104 | return true; 105 | } 106 | 107 | private boolean signOut() { 108 | Auth.GoogleSignInApi.signOut(googleApiClient); 109 | FirebaseAuth.getInstance().signOut(); 110 | return true; 111 | } 112 | 113 | private boolean signIn(boolean silent) { 114 | 115 | if(silent) { 116 | OptionalPendingResult result = Auth.GoogleSignInApi.silentSignIn(googleApiClient); 117 | if(result.isDone()) { 118 | handleSignInResult(result.get()); 119 | } else { 120 | result.setResultCallback(this); 121 | } 122 | } else { 123 | Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(googleApiClient); 124 | this.cordova.startActivityForResult(this, signInIntent, RC_SIGN_IN); 125 | } 126 | return true; 127 | } 128 | 129 | private boolean initialize(JSONArray args, CallbackContext callbackContext) { 130 | 131 | JSONArray allowedDomains = args.optJSONArray(0); 132 | this.allowedDomains = new ArrayList<>(); 133 | 134 | if(allowedDomains != null) { 135 | for (int i=0; i < allowedDomains.length(); i++) { 136 | this.allowedDomains.add(allowedDomains.optString(i)); 137 | } 138 | } 139 | 140 | if (eventContext == null) { 141 | eventContext = callbackContext; 142 | } 143 | return true; 144 | } 145 | 146 | private void raiseEvent(String type) { 147 | raiseEvent(type, null); 148 | } 149 | 150 | private void raiseEvent(String type, Object data) { 151 | 152 | if (eventContext != null) { 153 | 154 | JSONObject event = new JSONObject(); 155 | try { 156 | event.put("type", type); 157 | event.put("data", data); 158 | } catch (JSONException e) { 159 | e.printStackTrace(); 160 | } 161 | PluginResult result = new PluginResult(PluginResult.Status.OK, event); 162 | result.setKeepCallback(true); 163 | eventContext.sendPluginResult(result); 164 | } 165 | } 166 | 167 | private void firebaseAuthWithGoogle(GoogleSignInAccount acct) { 168 | 169 | String email = acct.getEmail(); 170 | String domain = email.substring(email.indexOf('@') + 1); 171 | if(allowedDomains.size() == 0 || allowedDomains.contains(domain)) { 172 | AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null); 173 | firebaseAuth.signInWithCredential(credential).addOnCompleteListener(this); 174 | } else { 175 | if(googleApiClient.isConnected()) { 176 | Auth.GoogleSignInApi.signOut(googleApiClient); 177 | } 178 | JSONObject error = new JSONObject(); 179 | try { 180 | error.put("code", "domain_not_allowed"); 181 | error.put("message", "the domain [" + domain + "] is not allowed"); 182 | error.put("domain", domain); 183 | } catch (JSONException e) { 184 | } 185 | raiseEvent("signinfailure", error); 186 | } 187 | } 188 | 189 | @Override 190 | public void onStart() { 191 | if (!googleApiClient.isConnected() && !googleApiClient.isConnecting()) { 192 | googleApiClient.connect(); 193 | } 194 | } 195 | 196 | @Override 197 | public void onStop() { 198 | if (googleApiClient.isConnected() || googleApiClient.isConnecting()) { 199 | googleApiClient.disconnect(); 200 | } 201 | } 202 | 203 | @Override 204 | public void onActivityResult(int requestCode, int resultCode, Intent intent) { 205 | 206 | // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); 207 | if (requestCode == RC_SIGN_IN) { 208 | GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(intent); 209 | handleSignInResult(result); 210 | } 211 | } 212 | 213 | private void handleSignInResult(GoogleSignInResult result) { 214 | if (result.isSuccess()) { 215 | raiseEvent("authorizing"); 216 | firebaseAuthWithGoogle(result.getSignInAccount()); 217 | } else { 218 | JSONObject data = new JSONObject(); 219 | try { 220 | Status status = result.getStatus(); 221 | Object code = translateStatusCode(status.getStatusCode()); 222 | data.put("code", code); 223 | data.put("message", result.getStatus().toString()); 224 | } catch (JSONException e) { 225 | } 226 | raiseEvent("signinfailure", data); 227 | } 228 | } 229 | 230 | @Override 231 | public void onComplete(@NonNull Task task) { 232 | 233 | if (!task.isSuccessful()) { 234 | Exception err = task.getException(); 235 | JSONObject data = new JSONObject(); 236 | try { 237 | data.put("code", err.getClass().getSimpleName()); 238 | data.put("message", err.getMessage()); 239 | } catch (JSONException e) { 240 | } 241 | raiseEvent("signinfailure", data); 242 | } 243 | } 244 | 245 | @Override 246 | public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { 247 | 248 | final FirebaseUser user = firebaseAuth.getCurrentUser(); 249 | if (user != null) { 250 | user.getIdToken(false).addOnCompleteListener(new OnCompleteListener() { 251 | @Override 252 | public void onComplete(@NonNull Task task) { 253 | 254 | final JSONObject data = new JSONObject(); 255 | 256 | if(task.isSuccessful()) { 257 | 258 | String token = task.getResult().getToken(); 259 | 260 | if (token != null && !token.equals(currentToken)) { 261 | currentToken = token; 262 | try { 263 | data.put("token", token); 264 | data.put("name", user.getDisplayName()); 265 | data.put("email", user.getEmail()); 266 | data.put("id", user.getUid()); 267 | if (user.getPhotoUrl() != null) { 268 | data.put("photoUrl", user.getPhotoUrl().toString()); 269 | } 270 | } catch (JSONException e) { 271 | } 272 | raiseEvent("signinsuccess", data); 273 | } 274 | } else { 275 | 276 | Exception err = task.getException(); 277 | try { 278 | data.put("code", err.getClass().getSimpleName()); 279 | data.put("message", err.getMessage()); 280 | } catch (JSONException e) { 281 | } 282 | raiseEvent("signinfailure", data); 283 | } 284 | } 285 | }); 286 | } else if(currentToken != null){ 287 | raiseEvent("signoutsuccess"); 288 | currentToken = null; 289 | } 290 | } 291 | 292 | @Override 293 | public void onResult(@NonNull GoogleSignInResult googleSignInResult) { 294 | handleSignInResult(googleSignInResult); 295 | } 296 | 297 | private Object translateStatusCode(int statusCode) { 298 | switch(statusCode) { 299 | case -1: 300 | return "SUCCESS_CACHE"; 301 | case 0: 302 | return "SUCCESS"; 303 | case 2: 304 | return "SERVICE_VERSION_UPDATE_REQUIRED"; 305 | case 3: 306 | return "SERVICE_DISABLED"; 307 | case 4: 308 | return "SIGN_IN_REQUIRED"; 309 | case 5: 310 | return "INVALID_ACCOUNT"; 311 | case 6: 312 | return "RESOLUTION_REQUIRED"; 313 | case 7: 314 | return "NETWORK_ERROR"; 315 | case 8: 316 | return "INTERNAL_ERROR"; 317 | case 10: 318 | return "DEVELOPER_ERROR"; 319 | case 13: 320 | return "ERROR"; 321 | case 14: 322 | return "INTERRUPTED"; 323 | case 15: 324 | return "TIMEOUT"; 325 | case 16: 326 | return "CANCELED"; 327 | case 17: 328 | return "API_NOT_CONNECTED"; 329 | case 18: 330 | return "DEAD_CLIENT"; 331 | case 12500: 332 | return "SIGN_IN_FAILED"; 333 | case 12501: 334 | return "SIGN_IN_CANCELLED"; 335 | default: 336 | return statusCode; 337 | } 338 | } 339 | 340 | } 341 | 342 | 343 | -------------------------------------------------------------------------------- /src/android/plugin.gradle: -------------------------------------------------------------------------------- 1 | ext.postBuildExtras = { 2 | android { 3 | compileOptions { 4 | sourceCompatibility JavaVersion.VERSION_1_7 5 | targetCompatibility JavaVersion.VERSION_1_7 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /src/ios/AppDelegate+FirebaseAuthGooglePlugin.h: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | @interface AppDelegate (FirebaseAuthGooglePlugin) 4 | 5 | @end -------------------------------------------------------------------------------- /src/ios/AppDelegate+FirebaseAuthGooglePlugin.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate+FirebaseAuthGooglePlugin.h" 2 | #import 3 | #import 4 | 5 | static void swizzleMethod(Class class, SEL destinationSelector, SEL sourceSelector); 6 | 7 | @implementation AppDelegate (FirebaseAuthGooglePlugin) 8 | 9 | + (void)load { 10 | 11 | swizzleMethod([AppDelegate class], 12 | @selector(application:openURL:options:), 13 | @selector(identity_application:openURL:options:)); 14 | swizzleMethod([AppDelegate class], 15 | @selector(application:openURL:sourceApplication:annotation:), 16 | @selector(identity_application:openURL:sourceApplication:annotation:)); 17 | } 18 | 19 | #pragma mark - AppDelegate Swizzles 20 | 21 | - (BOOL)identity_application:(UIApplication *)app 22 | openURL:(NSURL *)url 23 | options:(NSDictionary *)options { 24 | return [[GIDSignIn sharedInstance] handleURL:url 25 | sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] 26 | annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]; 27 | } 28 | 29 | - (BOOL)identity_application:(UIApplication *)application 30 | openURL:(NSURL *)url 31 | sourceApplication:(NSString *)sourceApplication 32 | annotation:(id)annotation { 33 | return [[GIDSignIn sharedInstance] handleURL:url 34 | sourceApplication:sourceApplication 35 | annotation:annotation]; 36 | } 37 | @end 38 | 39 | static void swizzleMethod(Class class, SEL destinationSelector, SEL sourceSelector) { 40 | Method destinationMethod = class_getInstanceMethod(class, destinationSelector); 41 | Method sourceMethod = class_getInstanceMethod(class, sourceSelector); 42 | 43 | // If the method doesn't exist, add it. If it does exist, replace it with the given implementation. 44 | if (class_addMethod(class, destinationSelector, method_getImplementation(sourceMethod), method_getTypeEncoding(sourceMethod))) { 45 | class_replaceMethod(class, destinationSelector, method_getImplementation(destinationMethod), method_getTypeEncoding(destinationMethod)); 46 | } else { 47 | method_exchangeImplementations(destinationMethod, sourceMethod); 48 | } 49 | } -------------------------------------------------------------------------------- /src/ios/FirebaseAuthGooglePlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | @interface FirebaseAuthGooglePlugin : CDVPlugin 6 | 7 | - (void)initialize:(CDVInvokedUrlCommand *)command; 8 | - (void)signIn:(CDVInvokedUrlCommand *)command; 9 | - (void)signOut:(CDVInvokedUrlCommand *)command; 10 | - (void)getToken:(CDVInvokedUrlCommand *)command; 11 | @property (nonatomic) NSString *eventCallbackId; 12 | @property (strong, nonatomic) NSArray *allowedDomains; 13 | @end 14 | -------------------------------------------------------------------------------- /src/ios/FirebaseAuthGooglePlugin.m: -------------------------------------------------------------------------------- 1 | #import "FirebaseAuthGooglePlugin.h" 2 | @import Firebase; 3 | 4 | @implementation FirebaseAuthGooglePlugin 5 | 6 | - (void)initialize:(CDVInvokedUrlCommand *)command { 7 | 8 | [GIDSignIn sharedInstance].clientID = [FIRApp defaultApp].options.clientID; 9 | [GIDSignIn sharedInstance].uiDelegate = self.viewController; 10 | [GIDSignIn sharedInstance].delegate = self; 11 | self.allowedDomains = [command argumentAtIndex:0]; 12 | 13 | 14 | self.eventCallbackId = command.callbackId; 15 | } 16 | 17 | 18 | - (void)getToken:(CDVInvokedUrlCommand *)command { 19 | 20 | FIRUser *currentUser = [FIRAuth auth].currentUser; 21 | [currentUser getIDTokenForcingRefresh:YES 22 | completion:^(NSString *_Nullable idToken, 23 | NSError *_Nullable error) { 24 | 25 | NSDictionary *message; 26 | 27 | if (error) { 28 | message = @{ 29 | @"type": @"signinfailure", 30 | @"data": @{ 31 | @"code": [NSNumber numberWithInteger:error.code], 32 | @"message": error.description == nil ? [NSNull null] : error.description 33 | } 34 | }; 35 | CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR 36 | messageAsDictionary:@{ 37 | @"code": [NSNumber numberWithInteger:error.code], 38 | @"message": error.description == nil ? [NSNull null] : error.description 39 | }]; 40 | [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; 41 | 42 | } else { 43 | 44 | CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:idToken]; 45 | [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; 46 | } 47 | }]; 48 | 49 | } 50 | 51 | - (void)signIn:(CDVInvokedUrlCommand *)command { 52 | 53 | BOOL silent = [command.arguments[0] boolValue]; 54 | if(silent == YES) { 55 | [[GIDSignIn sharedInstance] signInSilently]; 56 | } else { 57 | [[GIDSignIn sharedInstance] signIn]; 58 | } 59 | } 60 | 61 | - (void)signOut:(CDVInvokedUrlCommand *)command { 62 | 63 | NSDictionary *message = nil; 64 | NSError *error; 65 | 66 | [[GIDSignIn sharedInstance] signOut]; 67 | [[FIRAuth auth] signOut:&error]; 68 | 69 | if (error == nil) { 70 | message = @{ 71 | @"type": @"signoutsuccess" 72 | }; 73 | } else { 74 | 75 | message = @{ 76 | @"type": @"signoutfailure", 77 | @"data": @{ 78 | @"code": [NSNumber numberWithInteger:error.code], 79 | @"message": error.description == nil ? [NSNull null] : error.description 80 | } 81 | }; 82 | } 83 | 84 | CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:message]; 85 | [pluginResult setKeepCallbackAsBool:YES]; 86 | [self.commandDelegate sendPluginResult:pluginResult callbackId:self.eventCallbackId]; 87 | } 88 | 89 | #pragma mark - Helper functions 90 | 91 | - (NSString *)toJSON:(NSDictionary *)data { 92 | NSError *error = nil; 93 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data options:NSJSONWritingPrettyPrinted error:&error]; 94 | 95 | return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 96 | } 97 | 98 | - (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error { 99 | 100 | NSDictionary *message = nil; 101 | if (error == nil) { 102 | if([self.allowedDomains indexOfObject: user.hostedDomain] == NSNotFound) { 103 | 104 | [[GIDSignIn sharedInstance] signOut]; 105 | CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:@{ 106 | @"type": @"signinfailure", 107 | @"data": @{ 108 | @"code": @"domain_not_allowed", 109 | @"domain": user.hostedDomain ? user.hostedDomain : @"gmail.com", 110 | @"message": @"the domain is not allowed" 111 | } 112 | }]; 113 | [pluginResult setKeepCallbackAsBool:YES]; 114 | [self.commandDelegate sendPluginResult:pluginResult callbackId:self.eventCallbackId]; 115 | } else { 116 | GIDAuthentication *authentication = user.authentication; 117 | FIRAuthCredential *credential = [FIRGoogleAuthProvider credentialWithIDToken:authentication.idToken 118 | accessToken:authentication.accessToken]; 119 | [[FIRAuth auth] signInWithCredential:credential 120 | completion:[self handleLogin]]; 121 | } 122 | } else { 123 | CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:@{ 124 | @"type": @"signinfailure", 125 | @"data": @{ 126 | @"code": @(error.code), 127 | @"message": error.description 128 | } 129 | }]; 130 | [pluginResult setKeepCallbackAsBool:YES]; 131 | [self.commandDelegate sendPluginResult:pluginResult callbackId:self.eventCallbackId]; 132 | } 133 | 134 | } 135 | 136 | - (void (^)(FIRAuthDataResult *, NSError *))handleLogin { 137 | return ^(FIRAuthDataResult *result, NSError *error) { 138 | 139 | if (error == nil) { 140 | FIRUser *user = result.user; 141 | FIRUser *currentUser = [FIRAuth auth].currentUser; 142 | [currentUser getIDTokenWithCompletion:^(NSString *_Nullable idToken, 143 | NSError *_Nullable error) { 144 | 145 | NSDictionary *message; 146 | 147 | if (error) { 148 | message = @{ 149 | @"type": @"signinfailure", 150 | @"data": @{ 151 | @"code": [NSNumber numberWithInteger:error.code], 152 | @"message": error.description == nil ? [NSNull null] : error.description 153 | } 154 | }; 155 | } else { 156 | 157 | message = @{ 158 | @"type": @"signinsuccess", 159 | @"data": @{ 160 | @"token": idToken, 161 | @"id": user.uid == nil ? [NSNull null] : user.uid, 162 | @"name": user.displayName == nil ? [NSNull null] : user.displayName, 163 | @"email": user.email == nil ? [NSNull null] : user.email, 164 | @"photoUrl": user.photoURL == nil ? [NSNull null] : [user.photoURL absoluteString] 165 | } 166 | }; 167 | } 168 | 169 | CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:message]; 170 | [pluginResult setKeepCallbackAsBool:YES]; 171 | [self.commandDelegate sendPluginResult:pluginResult callbackId:self.eventCallbackId]; 172 | 173 | }]; 174 | } else { 175 | NSDictionary *message = @{ 176 | @"type": @"signinfailure", 177 | @"data": @{ 178 | @"code": [NSNumber numberWithInteger:error.code], 179 | @"message": error.description == nil ? [NSNull null] : error.description 180 | } 181 | }; 182 | 183 | CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:message]; 184 | [pluginResult setKeepCallbackAsBool:YES]; 185 | [self.commandDelegate sendPluginResult:pluginResult callbackId:self.eventCallbackId]; 186 | } 187 | }; 188 | } 189 | 190 | - (void)signIn:(GIDSignIn *)signIn didDisconnectWithUser:(GIDGoogleUser *)user withError:(NSError *)error { 191 | 192 | NSDictionary *message = nil; 193 | if (error == nil) { 194 | GIDProfileData *profile = user.profile; 195 | message = @{ 196 | @"type": @"signoutsuccess" 197 | }; 198 | } else { 199 | message = @{ 200 | @"type": @"signoutfailure", 201 | @"data": @{ 202 | 203 | @"code": [NSNumber numberWithInteger:error.code], 204 | @"message": error.description ? error.description : [NSNull null] 205 | } 206 | }; 207 | } 208 | 209 | CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:message]; 210 | [pluginResult setKeepCallbackAsBool:YES]; 211 | [self.commandDelegate sendPluginResult:pluginResult callbackId:self.eventCallbackId]; 212 | } 213 | 214 | @end 215 | -------------------------------------------------------------------------------- /www/firebaseAuthGooglePlugin.js: -------------------------------------------------------------------------------- 1 | var exec = require('cordova/exec'); 2 | const PLUGIN_NAME = 'FirebaseAuthGooglePlugin'; 3 | 4 | function FirebaseAuth(options) { 5 | 6 | var self = this; 7 | options = options || {}; 8 | var allowDomains = options.allowDomains ? [].concat(options.allowDomains) : null; 9 | exec(dispatchEvent, null, PLUGIN_NAME, 'initialize', [allowDomains]); 10 | 11 | this.getToken = function(success, failure) { 12 | 13 | if(window.Promise) { 14 | return new Promise(function (resolve, reject) { 15 | 16 | exec(resolve, reject, PLUGIN_NAME, 'getToken', []); 17 | }); 18 | } else { 19 | return exec(success, failure, PLUGIN_NAME, 'getToken', []); 20 | } 21 | }; 22 | 23 | this.signIn = function (silent) { 24 | 25 | return exec(null, null, PLUGIN_NAME, 'signIn', [silent === true]); 26 | }; 27 | 28 | this.signOut = function () { 29 | 30 | return exec(null, null, PLUGIN_NAME, 'signOut', []); 31 | }; 32 | 33 | function dispatchEvent(event) { 34 | 35 | // dispatch a pre-sign event that can be cancelled 36 | if(event.type === 'signinsuccess') { 37 | 38 | var cancelled = !window.dispatchEvent(new CustomEvent('beforeSignInComplete', { 39 | detail: event.data, 40 | cancelable: true 41 | })); 42 | 43 | if(cancelled) { 44 | self.signOut(); 45 | } else { 46 | window.dispatchEvent(new CustomEvent(event.type, { 47 | detail: event.data, 48 | cancelable: true 49 | })); 50 | } 51 | } else { 52 | window.dispatchEvent(new CustomEvent(event.type, { 53 | detail: event.data, 54 | cancelable: true 55 | })); 56 | } 57 | } 58 | } 59 | 60 | if (typeof module !== undefined && module.exports) { 61 | 62 | module.exports = FirebaseAuth; 63 | } --------------------------------------------------------------------------------