From 48e2fcc4f2c19d4bb448eeacfde0bede9c869885 Mon Sep 17 00:00:00 2001 From: Matt Jeanes Date: Thu, 27 Oct 2016 11:53:59 -0400 Subject: [PATCH 01/62] Fix passedUser not being used, make it more clear what user is being used --- .../io/fullstack/firestack/FirestackAuth.java | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java index 29a4efb..77a997d 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java @@ -68,7 +68,7 @@ public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { WritableMap msgMap = Arguments.createMap(); msgMap.putString("eventName", "listenForAuth"); - if (user != null) { + if (FirestackAuthModule.this.user != null) { WritableMap userMap = getUserMap(); msgMap.putBoolean("authenticated", true); @@ -107,8 +107,8 @@ public void createUserWithEmail(final String email, final String password, final @Override public void onComplete(@NonNull Task task) { if (task.isSuccessful()) { - user = task.getResult().getUser(); - userCallback(user, onComplete); + FirestackAuthModule.this.user = task.getResult().getUser(); + userCallback(FirestackAuthModule.this.user, onComplete); }else{ userErrorCallback(task, onComplete); } @@ -125,8 +125,8 @@ public void signInWithEmail(final String email, final String password, final Cal @Override public void onComplete(@NonNull Task task) { if (task.isSuccessful()) { - user = task.getResult().getUser(); - userCallback(user, callback); + FirestackAuthModule.this.user = task.getResult().getUser(); + userCallback(FirestackAuthModule.this.user, callback); } else { userErrorCallback(task, callback); } @@ -156,8 +156,8 @@ public void onComplete(@NonNull Task task) { Log.d(TAG, "signInAnonymously:onComplete:" + task.isSuccessful()); if (task.isSuccessful()) { - user = task.getResult().getUser(); - anonymousUserCallback(user, callback); + FirestackAuthModule.this.user = task.getResult().getUser(); + anonymousUserCallback(FirestackAuthModule.this.user, callback); }else{ userErrorCallback(task, callback); } @@ -176,8 +176,8 @@ public void signInWithCustomToken(final String customToken, final Callback callb public void onComplete(@NonNull Task task) { Log.d(TAG, "signInWithCustomToken:onComplete:" + task.isSuccessful()); if (task.isSuccessful()) { - user = task.getResult().getUser(); - userCallback(user, callback); + FirestackAuthModule.this.user = task.getResult().getUser(); + userCallback(FirestackAuthModule.this.user, callback); } else { userErrorCallback(task, callback); } @@ -356,7 +356,7 @@ public void onComplete(@NonNull Task task) { @ReactMethod public void signOut(final Callback callback) { FirebaseAuth.getInstance().signOut(); - user = null; + this.user = null; WritableMap resp = Arguments.createMap(); resp.putString("status", "complete"); @@ -368,11 +368,11 @@ public void signOut(final Callback callback) { public void getCurrentUser(final Callback callback) { mAuth = FirebaseAuth.getInstance(); - user = mAuth.getCurrentUser(); - if(user == null){ + this.user = mAuth.getCurrentUser(); + if(this.user == null){ noUserCallback(callback); }else{ - userCallback(user, callback); + userCallback(this.user, callback); } } @@ -387,8 +387,8 @@ public void googleLogin(String IdToken, final Callback callback) { @Override public void onComplete(@NonNull Task task) { if (task.isSuccessful()) { - user = task.getResult().getUser(); - userCallback(user, callback); + FirestackAuthModule.this.user = task.getResult().getUser(); + userCallback(FirestackAuthModule.this.user, callback); }else{ userErrorCallback(task, callback); } @@ -406,8 +406,8 @@ public void facebookLogin(String Token, final Callback callback) { @Override public void onComplete(@NonNull Task task) { if (task.isSuccessful()) { - user = task.getResult().getUser(); - userCallback(user, callback); + FirestackAuthModule.this.user = task.getResult().getUser(); + userCallback(FirestackAuthModule.this.user, callback); }else{ userErrorCallback(task, callback); } @@ -421,18 +421,18 @@ public void userCallback(FirebaseUser passedUser, final Callback onComplete) { if (passedUser == null) { mAuth = FirebaseAuth.getInstance(); - final FirebaseUser user = mAuth.getCurrentUser(); + this.user = mAuth.getCurrentUser(); } else { - final FirebaseUser user = passedUser; + this.user = passedUser; } - user.getToken(true).addOnCompleteListener(new OnCompleteListener() { + this.user.getToken(true).addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { WritableMap msgMap = Arguments.createMap(); WritableMap userMap = Arguments.createMap(); - if (user != null) { + if (FirestackAuthModule.this.user != null) { final String token = task.getResult().getToken(); userMap.putString("token", token); @@ -452,18 +452,18 @@ public void anonymousUserCallback(FirebaseUser passedUser, final Callback onComp if (passedUser == null) { mAuth = FirebaseAuth.getInstance(); - final FirebaseUser user = mAuth.getCurrentUser(); + this.user = mAuth.getCurrentUser(); } else { - final FirebaseUser user = passedUser; + this.user = passedUser; } - user.getToken(true).addOnCompleteListener(new OnCompleteListener() { + this.user.getToken(true).addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { WritableMap msgMap = Arguments.createMap(); WritableMap userMap = Arguments.createMap(); - if (user != null) { + if (FirestackAuthModule.this.user != null) { final String token = task.getResult().getToken(); userMap.putString("token", token); From e7a8662d599dbfcf359376470949468ebc522033 Mon Sep 17 00:00:00 2001 From: Matt Jeanes Date: Fri, 28 Oct 2016 15:06:23 -0400 Subject: [PATCH 02/62] Android: fix userMap not being used in userCallback & anonymousUserCallback --- .../io/fullstack/firestack/FirestackAuth.java | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java index 77a997d..7c0c2bb 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java @@ -417,7 +417,6 @@ public void onComplete(@NonNull Task task) { // Internal helpers public void userCallback(FirebaseUser passedUser, final Callback onComplete) { - WritableMap userMap = getUserMap(); if (passedUser == null) { mAuth = FirebaseAuth.getInstance(); @@ -429,14 +428,13 @@ public void userCallback(FirebaseUser passedUser, final Callback onComplete) { this.user.getToken(true).addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { - WritableMap msgMap = Arguments.createMap(); - WritableMap userMap = Arguments.createMap(); - + WritableMap msgMap = Arguments.createMap(); + WritableMap userMap = getUserMap(); if (FirestackAuthModule.this.user != null) { - final String token = task.getResult().getToken(); + final String token = task.getResult().getToken(); - userMap.putString("token", token); - userMap.putBoolean("anonymous", false); + userMap.putString("token", token); + userMap.putBoolean("anonymous", false); } msgMap.putMap("user", userMap); @@ -448,7 +446,6 @@ public void onComplete(@NonNull Task task) { // TODO: Reduce to one method public void anonymousUserCallback(FirebaseUser passedUser, final Callback onComplete) { - WritableMap userMap = getUserMap(); if (passedUser == null) { mAuth = FirebaseAuth.getInstance(); @@ -460,14 +457,14 @@ public void anonymousUserCallback(FirebaseUser passedUser, final Callback onComp this.user.getToken(true).addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { - WritableMap msgMap = Arguments.createMap(); - WritableMap userMap = Arguments.createMap(); + WritableMap msgMap = Arguments.createMap(); + WritableMap userMap = getUserMap(); if (FirestackAuthModule.this.user != null) { - final String token = task.getResult().getToken(); + final String token = task.getResult().getToken(); - userMap.putString("token", token); - userMap.putBoolean("anonymous", true); + userMap.putString("token", token); + userMap.putBoolean("anonymous", true); } msgMap.putMap("user", userMap); From 54a564cc4ca5bd7334360036ae3017315e337023 Mon Sep 17 00:00:00 2001 From: Matt Jeanes Date: Tue, 1 Nov 2016 10:07:24 -0400 Subject: [PATCH 03/62] Upgrade google play services and firebase to 9.8.0 --- android/build.gradle | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 4009637..a06d876 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -20,13 +20,13 @@ android { dependencies { compile 'com.facebook.react:react-native:0.20.+' - compile 'com.google.android.gms:play-services-base:9.6.1' + compile 'com.google.android.gms:play-services-base:9.8.0' - compile 'com.google.firebase:firebase-core:9.6.0' - compile 'com.google.firebase:firebase-auth:9.6.0' - compile 'com.google.firebase:firebase-analytics:9.6.0' - compile 'com.google.firebase:firebase-database:9.6.0' - compile 'com.google.firebase:firebase-storage:9.6.0' - compile 'com.google.firebase:firebase-messaging:9.6.0' + compile 'com.google.firebase:firebase-core:9.8.0' + compile 'com.google.firebase:firebase-auth:9.8.0' + compile 'com.google.firebase:firebase-analytics:9.8.0' + compile 'com.google.firebase:firebase-database:9.8.0' + compile 'com.google.firebase:firebase-storage:9.8.0' + compile 'com.google.firebase:firebase-messaging:9.8.0' } From 2bd1545e77ed3289f5c4d5b0287b31d4cc624049 Mon Sep 17 00:00:00 2001 From: "JSapp.me" Date: Tue, 1 Nov 2016 13:49:16 -0600 Subject: [PATCH 04/62] Add the ranking best practice strategy --- README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/README.md b/README.md index 0ebacc6..f531d23 100644 --- a/README.md +++ b/README.md @@ -640,6 +640,42 @@ And we also export the filetype constants as well: The native Firebase JavaScript library provides a featureful realtime database that works out of the box. Firestack provides an attribute to interact with the database without needing to configure the JS library. +Ranking strategy + +Add a new record with timestamp using this solution: + +firebaseApp.database.ref('posts').push().then((res) => { + let newPostKey = res.key; + firebaseApp.ServerValue.then(map => { + const postData = { + name: name, + timestamp: map.TIMESTAMP, + text: this.state.postText, + title: this.state.postTitle, + puid: newPostKey + } + let updates = {} + updates['/posts/' + newPostKey] = postData + firebaseApp.database.ref().update(updates).then(() => { + this.setState({ + postStatus: 'Posted! Thank You.', + postText: '', + }); + }).catch(() => { + this.setState({ postStatus: 'Something went wrong!!!' }); + }) + }) +}) + +Then retrieve the feed using this: + +firebaseApp.database.ref('posts').orderByChild('timestamp').limitToLast(30).once('value') +.then((snapshot) => { + this.props.savePosts(snapshot.val()) + const val = snapshot.val(); + console.log(val); +}) + #### DatabaseRef Firestack attempts to provide the same API as the JS Firebase library for both Android and iOS platforms. [Check out the firebase guide](https://firebase.google.com/docs/database/web/read-and-write) for more information on how to use the JS library. From f484cbdebf70892ec883e1811ce7c8573f01e984 Mon Sep 17 00:00:00 2001 From: Matt Jeanes Date: Tue, 1 Nov 2016 16:04:26 -0400 Subject: [PATCH 05/62] Android: Fix .on() listeners not getting removed / called immediately on setup --- .../java/io/fullstack/firestack/FirestackDatabase.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java b/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java index 537638e..8b262a0 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java @@ -468,7 +468,8 @@ public void off(final String path, final String name, final Callback callback) { ref.removeChildEventListener(); } - this.removeDBHandle(path, name); + String key = this.keyPath(path, name); + this.removeDBHandle(key); Log.d(TAG, "Removed listener " + name); WritableMap resp = Arguments.createMap(); resp.putString("handle", path); @@ -583,12 +584,11 @@ private void saveDBHandle(final String path, final String eventName, final FirestackDBReference dbRef) { String key = this.keyPath(path, eventName); - this.removeDBHandle(key, eventName); + this.removeDBHandle(key); mDBListeners.put(key, dbRef); } - private void removeDBHandle(final String path, final String eventName) { - String key = this.keyPath(path, eventName); + private void removeDBHandle(final String key) { if (mDBListeners.containsKey(key)) { FirestackDBReference r = mDBListeners.get(key); r.cleanup(); From 7c8c0b95002d404868762ab7d2815d6fcd28f6af Mon Sep 17 00:00:00 2001 From: Matt Jeanes Date: Wed, 2 Nov 2016 12:49:13 -0400 Subject: [PATCH 06/62] Fix listeners getting called when it's not their turn --- .../firestack/FirestackDatabase.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java b/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java index 8b262a0..90fdf5f 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java @@ -64,30 +64,40 @@ public void addChildEventListener(final String name, final ReadableArray modifie mEventListener = new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) { - self.handleDatabaseEvent(name, mPath, dataSnapshot); + if (name.equals("child_added")) { + self.handleDatabaseEvent(name, mPath, dataSnapshot); + } } @Override public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) { - self.handleDatabaseEvent(name, mPath, dataSnapshot); + if (name.equals("child_changed")) { + self.handleDatabaseEvent(name, mPath, dataSnapshot); + } } @Override public void onChildRemoved(DataSnapshot dataSnapshot) { - self.handleDatabaseEvent(name, mPath, dataSnapshot); + if (name.equals("child_removed")) { + self.handleDatabaseEvent(name, mPath, dataSnapshot); + } } @Override public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) { - self.handleDatabaseEvent(name, mPath, dataSnapshot); + if (name.equals("child_moved")) { + self.handleDatabaseEvent(name, mPath, dataSnapshot); + } } @Override public void onCancelled(DatabaseError error) { - self.handleDatabaseError(name, mPath, error); + //if (name.equals("child_added")) { + //self.handleDatabaseError(name, mPath, error); + //} } }; - + Query ref = this.getDatabaseQueryAtPathAndModifiers(modifiers); ref.addChildEventListener(mEventListener); this.setListeningTo(mPath, name); From 28fdcd0738973a61ea5f7b01aaa0224225c31a1a Mon Sep 17 00:00:00 2001 From: Matt Jeanes Date: Thu, 3 Nov 2016 18:45:06 -0400 Subject: [PATCH 07/62] Fix Java Database Listeners Various fixes / changes: - dont call removeDBHandlers() when calling .on() - Dont destroy and recreate the monolithic listener for each path - handleDatabaseEvent only forwards it to javascript if anyone is listening to that eventType Previously: - Calling ref.on(eventType) would erase pre-existing listeners - eventType handlers were getting called with the wrong eventType --- .../firestack/FirestackDatabase.java | 86 ++++++++----------- 1 file changed, 35 insertions(+), 51 deletions(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java b/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java index caa3f00..d95a284 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java @@ -62,42 +62,34 @@ public void setModifiers(final ReadableArray modifiers) { public void addChildEventListener(final String name, final ReadableArray modifiers) { final FirestackDBReference self = this; - mEventListener = new ChildEventListener() { - @Override - public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) { - if (name.equals("child_added")) { - self.handleDatabaseEvent(name, mPath, dataSnapshot); + if (mEventListener == null) { + mEventListener = new ChildEventListener() { + @Override + public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) { + self.handleDatabaseEvent("child_added", mPath, dataSnapshot); } - } - @Override - public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) { - if (name.equals("child_changed")) { - self.handleDatabaseEvent(name, mPath, dataSnapshot); + @Override + public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) { + self.handleDatabaseEvent("child_changed", mPath, dataSnapshot); } - } - @Override - public void onChildRemoved(DataSnapshot dataSnapshot) { - if (name.equals("child_removed")) { - self.handleDatabaseEvent(name, mPath, dataSnapshot); + @Override + public void onChildRemoved(DataSnapshot dataSnapshot) { + self.handleDatabaseEvent("child_removed", mPath, dataSnapshot); } - } - @Override - public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) { - if (name.equals("child_moved")) { - self.handleDatabaseEvent(name, mPath, dataSnapshot); + @Override + public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) { + self.handleDatabaseEvent("child_moved", mPath, dataSnapshot); } - } - @Override - public void onCancelled(DatabaseError error) { - //if (name.equals("child_added")) { - //self.handleDatabaseError(name, mPath, error); - //} - } - }; + @Override + public void onCancelled(DatabaseError error) { + self.handleDatabaseError(name, mPath, error); + } + }; + } Query ref = this.getDatabaseQueryAtPathAndModifiers(modifiers); ref.addChildEventListener(mEventListener); @@ -196,8 +188,11 @@ public void removeValueEventListener() { } private void handleDatabaseEvent(final String name, final String path, final DataSnapshot dataSnapshot) { + if (!FirestackDBReference.this.isListeningTo(path, name)) { + return; + } WritableMap data = FirestackUtils.dataSnapshotToMap(name, path, dataSnapshot); - WritableMap evt = Arguments.createMap(); + WritableMap evt = Arguments.createMap(); evt.putString("eventName", name); evt.putString("path", path); evt.putMap("body", data); @@ -470,18 +465,8 @@ public void onOnce(final String path, @ReactMethod public void off(final String path, final String name, final Callback callback) { - // TODO - FirestackDBReference ref = this.getDBHandle(path, name); - - if (name.equals("value")) { - ref.removeValueEventListener(); - } else { - ref.removeChildEventListener(); - } - - String key = this.keyPath(path, name); - this.removeDBHandle(key); - Log.d(TAG, "Removed listener " + name); + String keyPath = this.keyPath(path, name); + this.removeDBHandle(keyPath); WritableMap resp = Arguments.createMap(); resp.putString("handle", path); resp.putString("result", "success"); @@ -582,26 +567,25 @@ private void handleCallback( } private FirestackDBReference getDBHandle(final String path, final String eventName) { - String key = this.keyPath(path, eventName); - if (!mDBListeners.containsKey(key)) { + String keyPath = this.keyPath(path, eventName); + if (!mDBListeners.containsKey(keyPath)) { ReactContext ctx = getReactApplicationContext(); - mDBListeners.put(key, new FirestackDBReference(ctx, path)); + mDBListeners.put(keyPath, new FirestackDBReference(ctx, path)); } - return mDBListeners.get(key); + return mDBListeners.get(keyPath); } private void saveDBHandle(final String path, final String eventName, final FirestackDBReference dbRef) { - String key = this.keyPath(path, eventName); - this.removeDBHandle(key); - mDBListeners.put(key, dbRef); + String keyPath = this.keyPath(path, eventName); + mDBListeners.put(keyPath, dbRef); } - private void removeDBHandle(final String key) { - if (mDBListeners.containsKey(key)) { - FirestackDBReference r = mDBListeners.get(key); + private void removeDBHandle(final String keyPath) { + if (mDBListeners.containsKey(keyPath)) { + FirestackDBReference r = mDBListeners.get(keyPath); r.cleanup(); } } From 39982937e945bd9997f28d1bfefec2d51d025938 Mon Sep 17 00:00:00 2001 From: Elliot Hesp Date: Fri, 4 Nov 2016 08:50:48 +0000 Subject: [PATCH 08/62] Remove auth methods from instance root & update documentation --- README.md | 26 ++++++++++++++------------ lib/modules/authentication.js | 14 +------------- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index f531d23..84c3333 100644 --- a/README.md +++ b/README.md @@ -280,12 +280,14 @@ All methods return a promise. Firestack handles authentication for us out of the box, both with email/password-based authentication and through oauth providers (with a separate library to handle oauth providers). +> Android requires the Google Play services to installed for authentication to function. + #### listenForAuth() Firebase gives us a reactive method for listening for authentication. That is we can set up a listener to call a method when the user logs in and out. To set up the listener, call the `listenForAuth()` method: ```javascript -firestack.listenForAuth(function(evt) { +firestack.auth.listenForAuth(function(evt) { // evt is the authentication event // it contains an `error` key for carrying the // error message in case of an error @@ -306,7 +308,7 @@ firestack.listenForAuth(function(evt) { We can remove this listener by calling the `unlistenForAuth()` method. This is important to release resources from our app when we don't need to hold on to the listener any longer. ```javascript -firestack.unlistenForAuth() +firestack.auth.unlistenForAuth() ``` #### createUserWithEmail() @@ -314,7 +316,7 @@ firestack.unlistenForAuth() We can create a user by calling the `createUserWithEmail()` function. The `createUserWithEmail()` accepts two parameters, an email and a password. ```javascript -firestack.createUserWithEmail('ari@fullstack.io', '123456') +firestack.auth.createUserWithEmail('ari@fullstack.io', '123456') .then((user) => { console.log('user created', user) }) @@ -342,7 +344,7 @@ firestack.auth.signInWithEmail('ari@fullstack.io', '123456') To sign a user using a self-signed custom token, use the `signInWithCustomToken()` function. It accepts one parameter, the custom token: ```javascript -firestack.signInWithCustomToken(TOKEN) +firestack.auth.signInWithCustomToken(TOKEN) .then((user) => { console.log('User successfully logged in', user) }) @@ -397,7 +399,7 @@ When the auth token has expired, we can ask firebase to reauthenticate with the We can update the current user's email by using the command: `updateUserEmail()`. It accepts a single argument: the user's new email: ```javascript -firestack.updateUserEmail('ari+rocks@fullstack.io') +firestack.auth.updateUserEmail('ari+rocks@fullstack.io') .then((res) => console.log('Updated user email')) .catch(err => console.error('There was an error updating user email')) ``` @@ -407,7 +409,7 @@ firestack.updateUserEmail('ari+rocks@fullstack.io') We can update the current user's password using the `updateUserPassword()` method. It accepts a single parameter: the new password for the current user ```javascript -firestack.updateUserPassword('somethingReallyS3cr3t733t') +firestack.auth.updateUserPassword('somethingReallyS3cr3t733t') .then(res => console.log('Updated user password')) .catch(err => console.error('There was an error updating your password')) ``` @@ -417,7 +419,7 @@ firestack.updateUserPassword('somethingReallyS3cr3t733t') To send a password reset for a user based upon their email, we can call the `sendPasswordResetWithEmail()` method. It accepts a single parameter: the email of the user to send a reset email. ```javascript -firestack.sendPasswordResetWithEmail('ari+rocks@fullstack.io') +firestack.auth.sendPasswordResetWithEmail('ari+rocks@fullstack.io') .then(res => console.log('Check your inbox for further instructions')) .catch(err => console.error('There was an error :(')) ``` @@ -431,7 +433,7 @@ It accepts a single parameter: * object which contains updated key/values for the user's profile. Possible keys are listed [here](https://firebase.google.com/docs/auth/ios/manage-users#update_a_users_profile). ```javascript -firestack.updateUserProfile({ +firestack.auth.updateUserProfile({ displayName: 'Ari Lerner' }) .then(res => console.log('Your profile has been updated')) @@ -443,7 +445,7 @@ firestack.updateUserProfile({ It's possible to delete a user completely from your account on Firebase. Calling the `deleteUser()` method will take care of this for you. ```javascript -firestack.deleteUser() +firestack.auth.deleteUser() .then(res => console.log('Sad to see you go')) .catch(err => console.error('There was an error - Now you are trapped!')) ``` @@ -453,7 +455,7 @@ firestack.deleteUser() If you want user's token, use `getToken()` method. ```javascript -firestack.getToken() +firestack.auth.getToken() .then(res => console.log(res.token)) .catch(err => console.error('error')) ``` @@ -463,7 +465,7 @@ firestack.getToken() To sign the current user out, use the `signOut()` method. It accepts no parameters ```javascript -firestack.signOut() +firestack.auth.signOut() .then(res => console.log('You have been signed out')) .catch(err => console.error('Uh oh... something weird happened')) ``` @@ -473,7 +475,7 @@ firestack.signOut() Although you _can_ get the current user using the `getCurrentUser()` method, it's better to use this from within the callback function provided by `listenForAuth()`. However, if you need to get the current user, call the `getCurrentUser()` method: ```javascript -firestack.getCurrentUser() +firestack.auth.getCurrentUser() .then(user => console.log('The currently logged in user', user)) .catch(err => console.error('An error occurred')) ``` diff --git a/lib/modules/authentication.js b/lib/modules/authentication.js index 12fdcd4..c06edfc 100644 --- a/lib/modules/authentication.js +++ b/lib/modules/authentication.js @@ -9,18 +9,6 @@ import { Base } from './base' export class Authentication extends Base { constructor(firestack, options={}) { super(firestack, options); - - this._addToFirestackInstance( - 'listenForAuth', 'unlistenForAuth', - 'createUserWithEmail', 'signInWithEmail', - 'signInAnonymously', - 'signInWithProvider', 'signInWithCustomToken', - 'reauthenticateWithCredentialForProvider', - 'updateUserEmail', 'updatePassword', - 'updateUserProfile', 'sendPasswordResetWithEmail', - 'deleteUser', 'getToken', - 'signOut', 'getCurrentUser' - ) } // Auth @@ -169,4 +157,4 @@ export class Authentication extends Base { } } -export default Authentication \ No newline at end of file +export default Authentication From eeeacc99c7600951974ce15fefe24b1c2a105766 Mon Sep 17 00:00:00 2001 From: Matt Jeanes Date: Fri, 4 Nov 2016 13:59:37 -0400 Subject: [PATCH 09/62] Cleanup listeners and add a little bit of documentation --- .../firestack/FirestackDatabase.java | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java b/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java index d95a284..61cda5d 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java @@ -3,16 +3,11 @@ import android.content.Context; import android.util.Log; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.ListIterator; -import java.util.ArrayList; import java.util.Map; import android.net.Uri; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; - import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; @@ -24,11 +19,6 @@ import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReactContext; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.OnFailureListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.FirebaseApp; - import com.google.firebase.database.FirebaseDatabase; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.ChildEventListener; @@ -146,6 +136,9 @@ public Boolean isListeningTo(final String path, final String evtName) { return mListeners.containsKey(key); } + /** + * Note: these path/eventType listeners only get removed when javascript calls .off() and cleanup is run on the entire path + */ public void setListeningTo(final String path, final String evtName) { String key = this.pathListeningKey(path, evtName); mListeners.put(key, true); @@ -179,12 +172,16 @@ public void removeChildEventListener() { } public void removeValueEventListener() { + DatabaseReference ref = this.getDatabaseRef(); if (mValueListener != null) { - DatabaseReference ref = this.getDatabaseRef(); ref.removeEventListener(mValueListener); this.notListeningTo(mPath, "value"); mValueListener = null; } + if (mOnceValueListener != null) { + ref.removeEventListener(mOnceValueListener); + mOnceValueListener = null; + } } private void handleDatabaseEvent(final String name, final String path, final DataSnapshot dataSnapshot) { @@ -435,7 +432,7 @@ public void on(final String path, final ReadableArray modifiers, final String name, final Callback callback) { - FirestackDBReference ref = this.getDBHandle(path, name); + FirestackDBReference ref = this.getDBHandle(path); WritableMap resp = Arguments.createMap(); @@ -445,7 +442,7 @@ public void on(final String path, ref.addChildEventListener(name, modifiers); } - this.saveDBHandle(path, name, ref); + this.saveDBHandle(path, ref); resp.putString("result", "success"); Log.d(TAG, "Added listener " + name + " for " + ref); @@ -459,14 +456,20 @@ public void onOnce(final String path, final String name, final Callback callback) { Log.d(TAG, "Setting one-time listener on event: " + name + " for path " + path); - FirestackDBReference ref = this.getDBHandle(path, "once"); + FirestackDBReference ref = this.getDBHandle(path); ref.addOnceValueEventListener(modifiers, callback); } + /** + * At the time of this writing, off() only gets called when there are no more subscribers to a given path. + * `mListeners` might therefore be out of sync (though javascript isnt listening for those eventTypes, so + * it doesn't really matter- just polluting the RN bridge a little more than necessary. + * off() should therefore clean *everything* up + */ @ReactMethod - public void off(final String path, final String name, final Callback callback) { - String keyPath = this.keyPath(path, name); - this.removeDBHandle(keyPath); + public void off(final String path, @Deprecated final String name, final Callback callback) { + this.removeDBHandle(path); + Log.d(TAG, "Removed listener " + path); WritableMap resp = Arguments.createMap(); resp.putString("handle", path); resp.putString("result", "success"); @@ -566,27 +569,24 @@ private void handleCallback( } } - private FirestackDBReference getDBHandle(final String path, final String eventName) { - String keyPath = this.keyPath(path, eventName); - if (!mDBListeners.containsKey(keyPath)) { + private FirestackDBReference getDBHandle(final String path) { + if (!mDBListeners.containsKey(path)) { ReactContext ctx = getReactApplicationContext(); - mDBListeners.put(keyPath, new FirestackDBReference(ctx, path)); + mDBListeners.put(path, new FirestackDBReference(ctx, path)); } - return mDBListeners.get(keyPath); + return mDBListeners.get(path); } - private void saveDBHandle(final String path, - final String eventName, - final FirestackDBReference dbRef) { - String keyPath = this.keyPath(path, eventName); - mDBListeners.put(keyPath, dbRef); + private void saveDBHandle(final String path, final FirestackDBReference dbRef) { + mDBListeners.put(path, dbRef); } - private void removeDBHandle(final String keyPath) { - if (mDBListeners.containsKey(keyPath)) { - FirestackDBReference r = mDBListeners.get(keyPath); + private void removeDBHandle(final String path) { + if (mDBListeners.containsKey(path)) { + FirestackDBReference r = mDBListeners.get(path); r.cleanup(); + mDBListeners.remove(path); } } From 4e18f7e83de80ab76b518deebdcb7ee5b4dd05bd Mon Sep 17 00:00:00 2001 From: Ari Lerner Date: Fri, 4 Nov 2016 16:54:33 -0700 Subject: [PATCH 10/62] Added url back into firestack storage android --- .../src/main/java/io/fullstack/firestack/FirestackStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackStorage.java b/android/src/main/java/io/fullstack/firestack/FirestackStorage.java index 667958e..25ca218 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackStorage.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackStorage.java @@ -112,7 +112,7 @@ public void onSuccess(final StorageMetadata storageMetadata) { metadata.putDouble("updated_at", storageMetadata.getUpdatedTimeMillis()); metadata.putString("md5hash", storageMetadata.getMd5Hash()); metadata.putString("encoding", storageMetadata.getContentEncoding()); - metadata.putString("downloadUrl", storageMetadata.getDownloadUrl().toString()); + res.putString("url", storageMetadata.getDownloadUrl().toString()); res.putMap("metadata", metadata); callback.invoke(null, res); From 6713c7e13b0799d7918d050e9365895291de73a5 Mon Sep 17 00:00:00 2001 From: Hamza Sharawi Date: Sun, 6 Nov 2016 11:40:42 +0200 Subject: [PATCH 11/62] Change getBinder to get bundle getBinder is introduced in API 18, any app with a minSdk below 18 will crash because getBinder is not there, so i changed it to getBundle which gives the same result according to the docs. --- .../java/io/fullstack/firestack/FirestackAnalytics.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackAnalytics.java b/android/src/main/java/io/fullstack/firestack/FirestackAnalytics.java index d1be2e6..ec67022 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackAnalytics.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackAnalytics.java @@ -213,14 +213,14 @@ private Bundle makeEventBundle(final String name, final Map map) String val = (String) map.get("flight_number"); bundle.putString(FirebaseAnalytics.Param.FLIGHT_NUMBER, val); } - + Iterator> entries = map.entrySet().iterator(); while (entries.hasNext()) { Map.Entry entry = entries.next(); - if (bundle.getBinder(entry.getKey()) == null) { + if (bundle.getBundle(entry.getKey()) == null) { bundle.putString(entry.getKey(), entry.getValue().toString()); } } return bundle; } -} \ No newline at end of file +} From ed409a2c7a04a8cfc832bf05ffb3b4912ce53dcd Mon Sep 17 00:00:00 2001 From: kphayen Date: Mon, 7 Nov 2016 17:52:49 -0700 Subject: [PATCH 12/62] Implement reauthenticateWithCredentialForProvider for Android --- .../io/fullstack/firestack/FirestackAuth.java | 39 +++++++++++++++++-- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java index 7c0c2bb..d171c90 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java @@ -187,10 +187,41 @@ public void onComplete(@NonNull Task task) { @ReactMethod public void reauthenticateWithCredentialForProvider(final String provider, final String authToken, final String authSecret, final Callback callback) { - // TODO: - FirestackUtils.todoNote(TAG, "reauthenticateWithCredentialForProvider", callback); - // AuthCredential credential; - // Log.d(TAG, "reauthenticateWithCredentialForProvider called with: " + provider); + AuthCredential credential; + + if (provider.equals("facebook")) { + credential = FacebookAuthProvider.getCredential(authToken); + } else if (provider.equals("google")) { + credential = GoogleAuthProvider.getCredential(authToken, null); + } else { + // TODO: + FirestackUtils.todoNote(TAG, "reauthenticateWithCredentialForProvider", callback); + // AuthCredential credential; + // Log.d(TAG, "reauthenticateWithCredentialForProvider called with: " + provider); + return; + } + + FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); + if (user != null) { + user.reauthenticate(credential) + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + Log.d(TAG, "User re-authenticated with " + provider); + FirebaseUser u = FirebaseAuth.getInstance().getCurrentUser(); + userCallback(u, callback); + } else { + userErrorCallback(task, callback); + } + } + }); + } else { + WritableMap err = Arguments.createMap(); + err.putInt("errorCode", NO_CURRENT_USER); + err.putString("errorMessage", "No current user"); + callback.invoke(err); + } } @ReactMethod From 972b16d27d83791db5ff66f043bab883d9270762 Mon Sep 17 00:00:00 2001 From: Chaitanya Bhagvan Date: Tue, 8 Nov 2016 19:24:04 +0530 Subject: [PATCH 13/62] Catch exception thrown by setPersistenceEnabled which was causing the rn app to fail --- android/.idea/gradle.xml | 1 + .../main/java/io/fullstack/firestack/FirestackDatabase.java | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/android/.idea/gradle.xml b/android/.idea/gradle.xml index f4f39e8..76a4349 100644 --- a/android/.idea/gradle.xml +++ b/android/.idea/gradle.xml @@ -5,6 +5,7 @@ diff --git a/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java b/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java index 61cda5d..37aeca3 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackDatabase.java @@ -304,8 +304,12 @@ public String getName() { public void enablePersistence( final Boolean enable, final Callback callback) { - FirebaseDatabase.getInstance() + try { + FirebaseDatabase.getInstance() .setPersistenceEnabled(enable); + } catch (Throwable t) { + Log.e(TAG, "FirebaseDatabase setPersistenceEnabled exception", t); + } WritableMap res = Arguments.createMap(); res.putString("status", "success"); From a4a115f16d55fd9052b5f68d72936d067c67f193 Mon Sep 17 00:00:00 2001 From: Chaitanya Bhagvan Date: Tue, 8 Nov 2016 19:25:36 +0530 Subject: [PATCH 14/62] Parity in response format between ios and android --- .../java/io/fullstack/firestack/FirestackAuth.java | 4 ++-- ios/Firestack/FirestackAuth.m | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java index 7c0c2bb..7d3f889 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java @@ -432,7 +432,6 @@ public void onComplete(@NonNull Task task) { WritableMap userMap = getUserMap(); if (FirestackAuthModule.this.user != null) { final String token = task.getResult().getToken(); - userMap.putString("token", token); userMap.putBoolean("anonymous", false); } @@ -509,9 +508,10 @@ private WritableMap getUserMap() { userMap.putString("email", email); userMap.putString("uid", uid); userMap.putString("providerId", provider); + userMap.putBoolean("emailVerified", user.isEmailVerified()); if (name != null) { - userMap.putString("name", name); + userMap.putString("displayName", name); } if (photoUrl != null) { diff --git a/ios/Firestack/FirestackAuth.m b/ios/Firestack/FirestackAuth.m index 0eba61c..287c52b 100644 --- a/ios/Firestack/FirestackAuth.m +++ b/ios/Firestack/FirestackAuth.m @@ -25,7 +25,7 @@ @implementation FirestackAuth if (!user) { NSDictionary *evt = @{ @"eventName": AUTH_ANONYMOUS_ERROR_EVENT, - @"msg": [error localizedDescription] + @"errorMessage": [error localizedDescription] }; @@ -41,7 +41,7 @@ @implementation FirestackAuth } @catch(NSException *ex) { NSDictionary *eventError = @{ @"eventName": AUTH_ANONYMOUS_ERROR_EVENT, - @"msg": ex.reason + @"errorMessage": ex.reason }; [self sendJSEvent:AUTH_ERROR_EVENT @@ -144,14 +144,15 @@ @implementation FirestackAuth sendJSEvent:AUTH_CHANGED_EVENT props: @{ @"eventName": @"userTokenError", - @"msg": [error localizedFailureReason] + @"authenticated": @((BOOL)true), + @"errorMessage": [error localizedFailureReason] }]; } else { [self sendJSEvent:AUTH_CHANGED_EVENT props: @{ @"eventName": @"user", - @"authenticated": @(true), + @"authenticated": @((BOOL)true), @"user": userProps }]; } @@ -164,7 +165,7 @@ @implementation FirestackAuth [self sendJSEvent:AUTH_CHANGED_EVENT props:@{ @"eventName": @"no_user", - @"authenticated": @(false), + @"authenticated": @((BOOL)false), @"error": err }]; } From 483e15fd4b7a8256bec99771220c4cc9721e198a Mon Sep 17 00:00:00 2001 From: Chaitanya Bhagvan Date: Tue, 8 Nov 2016 20:19:53 +0530 Subject: [PATCH 15/62] Fixed a typo that was causing an error --- lib/modules/database.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/modules/database.js b/lib/modules/database.js index f7f91fe..0cf1382 100644 --- a/lib/modules/database.js +++ b/lib/modules/database.js @@ -232,7 +232,7 @@ class DatabaseRef extends ReferenceBase { const path = this.dbPath(); return this.db.off(path, evt, origCB) .then(({callback, subscriptions}) => { - if (dbSubscriptions[path] && dbSubscriptions[path][evt].length > 0) { + if (subscriptions[path] && subscriptions[path][evt].length > 0) { return subscriptions; } @@ -514,4 +514,4 @@ export class Database extends Base { } } -export default Database \ No newline at end of file +export default Database From a85f5facacc4ecb6af0924e88c222f6d4d4c3747 Mon Sep 17 00:00:00 2001 From: Chaitanya Bhagvan Date: Wed, 9 Nov 2016 14:50:11 +0530 Subject: [PATCH 16/62] Parity in response format between ios and android --- ios/Firestack/FirestackAuth.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ios/Firestack/FirestackAuth.m b/ios/Firestack/FirestackAuth.m index 287c52b..bcd0919 100644 --- a/ios/Firestack/FirestackAuth.m +++ b/ios/Firestack/FirestackAuth.m @@ -186,7 +186,8 @@ @implementation FirestackAuth FIRUser *user = [FIRAuth auth].currentUser; if (user != nil) { - NSDictionary *userProps = [self userPropsFromFIRUser:user]; + NSMutableDictionary *userProps = [self userPropsFromFIRUser:user]; + [userProps setValue: @((BOOL)true) forKey: @"authenticated"]; callback(@[[NSNull null], userProps]); } else { // No user is signed in. From e34988b436d027ca9ec1f036d07d79c10748e1ec Mon Sep 17 00:00:00 2001 From: Chaitanya Bhagvan Date: Wed, 9 Nov 2016 19:22:55 +0530 Subject: [PATCH 17/62] Reverted changes since it was an error from my end --- lib/modules/database.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/modules/database.js b/lib/modules/database.js index 0cf1382..6affe14 100644 --- a/lib/modules/database.js +++ b/lib/modules/database.js @@ -232,7 +232,7 @@ class DatabaseRef extends ReferenceBase { const path = this.dbPath(); return this.db.off(path, evt, origCB) .then(({callback, subscriptions}) => { - if (subscriptions[path] && subscriptions[path][evt].length > 0) { + if (dbSubscriptions[path] && dbSubscriptions[path][evt].length > 0) { return subscriptions; } From 68396e07542cedd66fd61fad48554f5cdebd8430 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Wed, 9 Nov 2016 14:53:22 +0000 Subject: [PATCH 18/62] fixing filter value creation --- lib/modules/database.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/modules/database.js b/lib/modules/database.js index f7f91fe..b87d429 100644 --- a/lib/modules/database.js +++ b/lib/modules/database.js @@ -113,7 +113,7 @@ class DatabaseQuery { .forEach(key => { const filter = this.filters[key]; if (filter) { - const filterArgs = [key, filter].join(argsSeparator) + const filterArgs = ([key].concat(filter)).join(argsSeparator) modifiers.push(filterArgs); } }) From 431f10b87f9b72a0eeee2bd6161c09e56820404c Mon Sep 17 00:00:00 2001 From: Matt Jeanes Date: Fri, 4 Nov 2016 17:59:54 -0400 Subject: [PATCH 19/62] Fix Storage on android --- .../src/main/java/io/fullstack/firestack/FirestackStorage.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackStorage.java b/android/src/main/java/io/fullstack/firestack/FirestackStorage.java index 25ca218..210a1bd 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackStorage.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackStorage.java @@ -96,8 +96,9 @@ public void onSuccess(Uri uri) { res.putString("bucket", storageRef.getBucket()); res.putString("fullPath", uri.toString()); res.putString("path", uri.getPath()); + res.putString("url", uri.toString()); - storageRef.getMetadata() + fileRef.getMetadata() .addOnSuccessListener(new OnSuccessListener() { @Override public void onSuccess(final StorageMetadata storageMetadata) { From c3129fbb16663c4813b5c4b2fa58265e33c41a31 Mon Sep 17 00:00:00 2001 From: ghuh Date: Wed, 9 Nov 2016 19:04:54 -0700 Subject: [PATCH 20/62] Fix Android listenForAuth method to correctly check for user --- android/src/main/java/io/fullstack/firestack/FirestackAuth.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java index e9ec2bf..9f1372a 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java @@ -68,7 +68,7 @@ public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { WritableMap msgMap = Arguments.createMap(); msgMap.putString("eventName", "listenForAuth"); - if (FirestackAuthModule.this.user != null) { + if (firebaseAuth.getCurrentUser() != null) { WritableMap userMap = getUserMap(); msgMap.putBoolean("authenticated", true); From 28644a6560e12576b7243732f46ae1a7990decc1 Mon Sep 17 00:00:00 2001 From: Ari Lerner Date: Wed, 9 Nov 2016 20:26:11 -0800 Subject: [PATCH 21/62] WIP: FirebaseAuth --- .../io/fullstack/firestack/FirestackAuth.java | 193 +++++++++++++----- lib/utils/window-or-global.js | 2 +- 2 files changed, 138 insertions(+), 57 deletions(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java index e9ec2bf..050768e 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java @@ -1,3 +1,4 @@ + package io.fullstack.firestack; import android.content.Context; @@ -99,7 +100,7 @@ public void unlistenForAuth(final Callback callback) { } @ReactMethod - public void createUserWithEmail(final String email, final String password, final Callback onComplete) { + public void createUserWithEmail(final String email, final String password, final Callback callback) { mAuth = FirebaseAuth.getInstance(); mAuth.createUserWithEmailAndPassword(email, password) @@ -107,13 +108,18 @@ public void createUserWithEmail(final String email, final String password, final @Override public void onComplete(@NonNull Task task) { if (task.isSuccessful()) { - FirestackAuthModule.this.user = task.getResult().getUser(); - userCallback(FirestackAuthModule.this.user, onComplete); - }else{ - userErrorCallback(task, onComplete); + FirestackAuthModule.this.user = task.getResult().getUser(); + userCallback(FirestackAuthModule.this.user, callback); + } else { + // userErrorCallback(task, callback); } } - }); + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception ex) { + userExceptionCallback(ex, callback); + } + }); } @ReactMethod @@ -125,13 +131,19 @@ public void signInWithEmail(final String email, final String password, final Cal @Override public void onComplete(@NonNull Task task) { if (task.isSuccessful()) { - FirestackAuthModule.this.user = task.getResult().getUser(); - userCallback(FirestackAuthModule.this.user, callback); + FirestackAuthModule.this.user = task.getResult().getUser(); + userCallback(FirestackAuthModule.this.user, callback); } else { - userErrorCallback(task, callback); + // userErrorCallback(task, callback); } + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception ex) { + Log.e(TAG, "An exception occurred: " + ex.getMessage()); + userExceptionCallback(ex, callback); } - }); + }); } @ReactMethod @@ -156,14 +168,18 @@ public void onComplete(@NonNull Task task) { Log.d(TAG, "signInAnonymously:onComplete:" + task.isSuccessful()); if (task.isSuccessful()) { - FirestackAuthModule.this.user = task.getResult().getUser(); - anonymousUserCallback(FirestackAuthModule.this.user, callback); - }else{ - userErrorCallback(task, callback); + FirestackAuthModule.this.user = task.getResult().getUser(); + anonymousUserCallback(FirestackAuthModule.this.user, callback); + } else { + // userErrorCallback(task, callback); } - } - }); - + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception ex) { + userExceptionCallback(ex, callback); + } + }); } @ReactMethod @@ -175,14 +191,19 @@ public void signInWithCustomToken(final String customToken, final Callback callb @Override public void onComplete(@NonNull Task task) { Log.d(TAG, "signInWithCustomToken:onComplete:" + task.isSuccessful()); - if (task.isSuccessful()) { - FirestackAuthModule.this.user = task.getResult().getUser(); + if (task.isSuccessful()) { + FirestackAuthModule.this.user = task.getResult().getUser(); userCallback(FirestackAuthModule.this.user, callback); - } else { - userErrorCallback(task, callback); - } + } else { + // userErrorCallback(task, callback); + } } - }); + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception ex) { + userExceptionCallback(ex, callback); + } + }); } @ReactMethod @@ -212,7 +233,7 @@ public void onComplete(@NonNull Task task) { FirebaseUser u = FirebaseAuth.getInstance().getCurrentUser(); userCallback(u, callback); } else { - userErrorCallback(task, callback); + // userErrorCallback(task, callback); } } }); @@ -238,10 +259,15 @@ public void onComplete(@NonNull Task task) { FirebaseUser u = FirebaseAuth.getInstance().getCurrentUser(); userCallback(u, callback); } else { - userErrorCallback(task, callback); + // userErrorCallback(task, callback); } } - }); + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception ex) { + userExceptionCallback(ex, callback); + } + }); } else { WritableMap err = Arguments.createMap(); err.putInt("errorCode", NO_CURRENT_USER); @@ -265,10 +291,15 @@ public void onComplete(@NonNull Task task) { FirebaseUser u = FirebaseAuth.getInstance().getCurrentUser(); userCallback(u, callback); } else { - userErrorCallback(task, callback); + // userErrorCallback(task, callback); } } - }); + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception ex) { + userExceptionCallback(ex, callback); + } + }); } else { WritableMap err = Arguments.createMap(); err.putInt("errorCode", NO_CURRENT_USER); @@ -289,11 +320,16 @@ public void onComplete(@NonNull Task task) { WritableMap resp = Arguments.createMap(); resp.putString("status", "complete"); callback.invoke(null, resp); - }else{ + } else { callback.invoke(task.getException().toString()); } } - }); + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception ex) { + userExceptionCallback(ex, callback); + } + }); } @ReactMethod @@ -312,10 +348,15 @@ public void onComplete(@NonNull Task task) { resp.putString("msg", "User account deleted"); callback.invoke(null, resp); } else { - userErrorCallback(task, callback); + // userErrorCallback(task, callback); } } - }); + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception ex) { + userExceptionCallback(ex, callback); + } + }); } else { WritableMap err = Arguments.createMap(); err.putInt("errorCode", NO_CURRENT_USER); @@ -345,7 +386,12 @@ public void onComplete(@NonNull Task task) { callback.invoke(err); } } - }); + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception ex) { + userExceptionCallback(ex, callback); + } + }); } @ReactMethod @@ -378,10 +424,15 @@ public void onComplete(@NonNull Task task) { FirebaseUser u = FirebaseAuth.getInstance().getCurrentUser(); userCallback(u, callback); } else { - userErrorCallback(task, callback); + // userErrorCallback(task, callback); } } - }); + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception ex) { + userExceptionCallback(ex, callback); + } + }); } @ReactMethod @@ -417,14 +468,19 @@ public void googleLogin(String IdToken, final Callback callback) { .addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { - if (task.isSuccessful()) { - FirestackAuthModule.this.user = task.getResult().getUser(); - userCallback(FirestackAuthModule.this.user, callback); - }else{ - userErrorCallback(task, callback); - } + if (task.isSuccessful()) { + FirestackAuthModule.this.user = task.getResult().getUser(); + userCallback(FirestackAuthModule.this.user, callback); + }else{ + // userErrorCallback(task, callback); + } } - }); + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception ex) { + userExceptionCallback(ex, callback); + } + }); } @ReactMethod @@ -436,18 +492,23 @@ public void facebookLogin(String Token, final Callback callback) { .addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { - if (task.isSuccessful()) { - FirestackAuthModule.this.user = task.getResult().getUser(); - userCallback(FirestackAuthModule.this.user, callback); - }else{ - userErrorCallback(task, callback); - } + if (task.isSuccessful()) { + FirestackAuthModule.this.user = task.getResult().getUser(); + userCallback(FirestackAuthModule.this.user, callback); + }else{ + // userErrorCallback(task, callback); + } } - }); + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception ex) { + userExceptionCallback(ex, callback); + } + }); } // Internal helpers - public void userCallback(FirebaseUser passedUser, final Callback onComplete) { + public void userCallback(FirebaseUser passedUser, final Callback callback) { if (passedUser == null) { mAuth = FirebaseAuth.getInstance(); @@ -469,13 +530,18 @@ public void onComplete(@NonNull Task task) { msgMap.putMap("user", userMap); - onComplete.invoke(null, msgMap); + callback.invoke(null, msgMap); } - }); + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception ex) { + userExceptionCallback(ex, callback); + } + }); } // TODO: Reduce to one method - public void anonymousUserCallback(FirebaseUser passedUser, final Callback onComplete) { + public void anonymousUserCallback(FirebaseUser passedUser, final Callback callback) { if (passedUser == null) { mAuth = FirebaseAuth.getInstance(); @@ -484,7 +550,8 @@ public void anonymousUserCallback(FirebaseUser passedUser, final Callback onComp this.user = passedUser; } - this.user.getToken(true).addOnCompleteListener(new OnCompleteListener() { + this.user.getToken(true) + .addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { WritableMap msgMap = Arguments.createMap(); @@ -499,9 +566,14 @@ public void onComplete(@NonNull Task task) { msgMap.putMap("user", userMap); - onComplete.invoke(null, msgMap); + callback.invoke(null, msgMap); } - }); + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception ex) { + userExceptionCallback(ex, callback); + } + }); } @@ -524,6 +596,15 @@ public void userErrorCallback(Task task, final Callback onFail) { onFail.invoke(error); } + public void userExceptionCallback(Exception ex, final Callback onFail) { + WritableMap error = Arguments.createMap(); + error.putInt("errorCode", ex.hashCode()); + error.putString("errorMessage", ex.getMessage()); + error.putString("allErrorMessage", ex.toString()); + + onFail.invoke(error); + } + private WritableMap getUserMap() { WritableMap userMap = Arguments.createMap(); diff --git a/lib/utils/window-or-global.js b/lib/utils/window-or-global.js index 3228c06..7b64020 100644 --- a/lib/utils/window-or-global.js +++ b/lib/utils/window-or-global.js @@ -2,4 +2,4 @@ // https://github.com/purposeindustries/window-or-global module.exports = (typeof self === 'object' && self.self === self && self) || (typeof global === 'object' && global.global === global && global) || - this \ No newline at end of file + {} \ No newline at end of file From 1111617f2b07e38b0ad1849c4eb919723da2ffc4 Mon Sep 17 00:00:00 2001 From: Ari Lerner Date: Thu, 10 Nov 2016 02:55:43 -0800 Subject: [PATCH 22/62] Added initial handling of android error messages --- .../io/fullstack/firestack/FirestackAuth.java | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java index 050768e..d9d4101 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java @@ -33,6 +33,7 @@ import com.google.firebase.auth.FirebaseUser; import com.google.firebase.auth.GetTokenResult; import com.google.firebase.auth.GoogleAuthProvider; +import com.google.firebase.auth.FirebaseAuthException; class FirestackAuthModule extends ReactContextBaseJavaModule { private final int NO_CURRENT_USER = 100; @@ -588,19 +589,21 @@ public void noUserCallback(final Callback callback) { } public void userErrorCallback(Task task, final Callback onFail) { - WritableMap error = Arguments.createMap(); - error.putInt("errorCode", task.getException().hashCode()); - error.putString("errorMessage", task.getException().getMessage()); - error.putString("allErrorMessage", task.getException().toString()); - - onFail.invoke(error); + userExceptionCallback(task.getException(), onFail); } - public void userExceptionCallback(Exception ex, final Callback onFail) { + public void userExceptionCallback(Exception exp, final Callback onFail) { WritableMap error = Arguments.createMap(); - error.putInt("errorCode", ex.hashCode()); - error.putString("errorMessage", ex.getMessage()); - error.putString("allErrorMessage", ex.toString()); + error.putString("errorMessage", exp.getMessage()); + error.putString("allErrorMessage", exp.toString()); + + try { + throw exp; + } catch (FirebaseAuthException ex) { + error.putString("errorCode", ex.getErrorCode()); + } catch (Exception ex) { + Log.e(TAG, ex.getMessage()); + } onFail.invoke(error); } @@ -636,3 +639,6 @@ private WritableMap getUserMap() { return userMap; } } +n userMap; + } +} From 7d09ab4a7aba582290e1bebf6692dadaba3e38e7 Mon Sep 17 00:00:00 2001 From: Chaitanya Bhagvan Date: Fri, 11 Nov 2016 20:30:56 +0530 Subject: [PATCH 23/62] Parity of response format between ios and android. Added authenticated flag to response from getCurrentUser --- android/src/main/java/io/fullstack/firestack/FirestackAuth.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java index a155612..36dd584 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java @@ -530,7 +530,7 @@ public void onComplete(@NonNull Task task) { } msgMap.putMap("user", userMap); - + msgMap.putBoolean("authenticated", true); callback.invoke(null, msgMap); } }).addOnFailureListener(new OnFailureListener() { From e5255698ae07a84e7e946c1666e1f430616581a1 Mon Sep 17 00:00:00 2001 From: Ari Lerner Date: Mon, 14 Nov 2016 08:22:34 -0800 Subject: [PATCH 24/62] Remove RCTConvert to work with react-native-fcm --- ios/Firestack/FirestackCloudMessaging.m | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/ios/Firestack/FirestackCloudMessaging.m b/ios/Firestack/FirestackCloudMessaging.m index 9cfa6b3..0a71a64 100644 --- a/ios/Firestack/FirestackCloudMessaging.m +++ b/ios/Firestack/FirestackCloudMessaging.m @@ -13,28 +13,7 @@ #endif #import "FirestackCloudMessaging.h" #import "FirestackEvents.h" -#import "RCTConvert.h" - -// https://github.com/facebook/react-native/blob/master/Libraries/PushNotificationIOS/RCTPushNotificationManager.m -@implementation RCTConvert (UILocalNotification) - -+ (UILocalNotification *)UILocalNotification:(id)json -{ - NSDictionary *details = [self NSDictionary:json]; - UILocalNotification *notification = [UILocalNotification new]; - notification.fireDate = [RCTConvert NSDate:details[@"fireDate"]] ?: [NSDate date]; - notification.alertBody = [RCTConvert NSString:details[@"alertBody"]]; - notification.alertAction = [RCTConvert NSString:details[@"alertAction"]]; - notification.soundName = [RCTConvert NSString:details[@"soundName"]] ?: UILocalNotificationDefaultSoundName; - notification.userInfo = [RCTConvert NSDictionary:details[@"userInfo"]]; - notification.category = [RCTConvert NSString:details[@"category"]]; - if (details[@"applicationIconBadgeNumber"]) { - notification.applicationIconBadgeNumber = [RCTConvert NSInteger:details[@"applicationIconBadgeNumber"]]; - } - return notification; -} - -@end +// #import "RCTConvert.h" @implementation FirestackCloudMessaging From 8306c45f3be5be063b3eebc362ea7d3ca1ab2505 Mon Sep 17 00:00:00 2001 From: Samer Date: Wed, 16 Nov 2016 14:38:18 +0100 Subject: [PATCH 25/62] Filter out undefined filters --- lib/modules/database.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/modules/database.js b/lib/modules/database.js index 5c4b27e..6ebdecc 100644 --- a/lib/modules/database.js +++ b/lib/modules/database.js @@ -111,9 +111,10 @@ class DatabaseQuery { } Object.keys(this.filters) .forEach(key => { - const filter = this.filters[key]; + let filter = this.filters[key]; if (filter) { - const filterArgs = ([key].concat(filter)).join(argsSeparator) + const cleanFilters = filter.filter((f) => typeof f !== "undefined"); + const filterArgs = ([key].concat(cleanFilters)).join(argsSeparator); modifiers.push(filterArgs); } }) From 487ed30886c1cba943d34cde67f565a0a92c4881 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Wed, 16 Nov 2016 18:23:19 +0000 Subject: [PATCH 26/62] removing trailing comma --- lib/modules/database.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/modules/database.js b/lib/modules/database.js index 5c4b27e..9956f39 100644 --- a/lib/modules/database.js +++ b/lib/modules/database.js @@ -96,7 +96,7 @@ class DatabaseQuery { } setFilter(name, ...args) { - this.filters[name] = args; + this.filters[name] = args.filter(n => n != undefined); return this.ref; } From 6ca78a19ea7d611605ddf82f151c13c6534ac098 Mon Sep 17 00:00:00 2001 From: Chaitanya Bhagvan Date: Thu, 17 Nov 2016 11:46:52 +0530 Subject: [PATCH 27/62] forEach and map method on the DataSnapshot does not retain key --- lib/modules/database.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/modules/database.js b/lib/modules/database.js index 5c4b27e..ff59c74 100644 --- a/lib/modules/database.js +++ b/lib/modules/database.js @@ -35,7 +35,7 @@ class DataSnapshot { forEach(fn) { (this.childKeys || []) - .forEach(key => fn(this.value[key])) + .forEach(key => fn({key: key, value: this.value[key]})) } map(fn) { From 80133de8316729a851610ee6d326c73a642dde32 Mon Sep 17 00:00:00 2001 From: Chaitanya Bhagvan Date: Thu, 17 Nov 2016 12:30:32 +0530 Subject: [PATCH 28/62] Fixed error calling length of undefined --- lib/modules/database.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/modules/database.js b/lib/modules/database.js index ff59c74..1112919 100644 --- a/lib/modules/database.js +++ b/lib/modules/database.js @@ -232,7 +232,7 @@ class DatabaseRef extends ReferenceBase { const path = this.dbPath(); return this.db.off(path, evt, origCB) .then(({callback, subscriptions}) => { - if (dbSubscriptions[path] && dbSubscriptions[path][evt].length > 0) { + if (dbSubscriptions[path] && dbSubscriptions[path][evt] && dbSubscriptions[path][evt].length > 0) { return subscriptions; } From d005ab2f966cca23e955ca79f109efbefced8772 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 17 Nov 2016 20:05:09 +0100 Subject: [PATCH 29/62] Use storage url from .plist file if not setStorageUrl() hasn't been called. - Fix weird error that NSError is not KVC compliant when storage is not configured JS - Fixed code seems to exist on several more locations but has not been fixed, since there are no tests to ensure I don't break anything. --- ios/Firestack/FirestackStorage.m | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ios/Firestack/FirestackStorage.m b/ios/Firestack/FirestackStorage.m index d88a19a..ff96646 100644 --- a/ios/Firestack/FirestackStorage.m +++ b/ios/Firestack/FirestackStorage.m @@ -52,14 +52,13 @@ - (dispatch_queue_t)methodQueue metadata:(NSDictionary *)metadata callback:(RCTResponseSenderBlock) callback) { + FIRStorageReference *storageRef; if (urlStr == nil) { - NSError *err = [[NSError alloc] init]; - [err setValue:@"Storage configuration error" forKey:@"name"]; - [err setValue:@"Call setStorageUrl() first" forKey:@"description"]; - return callback(@[err]); + storageRef = [[FIRStorage storage] reference]; + } else { + storageRef = [[FIRStorage storage] referenceForURL:urlStr]; } - FIRStorageReference *storageRef = [[FIRStorage storage] referenceForURL:urlStr]; FIRStorageReference *uploadRef = [storageRef child:name]; FIRStorageMetadata *firmetadata = [[FIRStorageMetadata alloc] initWithDictionary:metadata]; From dfc0bd1eb86706a421341fdf9b6a6f27e3931d97 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 17 Nov 2016 20:51:23 +0100 Subject: [PATCH 30/62] Fix donwloadUrl to use storageUrl from .plist. - Use storageUrl from default config if not set otherwise in JS - Similar code exists on several other places that are not fixed since no tests prevent breaking stuff. --- ios/Firestack/FirestackStorage.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ios/Firestack/FirestackStorage.m b/ios/Firestack/FirestackStorage.m index ff96646..b87d394 100644 --- a/ios/Firestack/FirestackStorage.m +++ b/ios/Firestack/FirestackStorage.m @@ -25,7 +25,12 @@ - (dispatch_queue_t)methodQueue path:(NSString *) path callback:(RCTResponseSenderBlock) callback) { - FIRStorageReference *storageRef = [[FIRStorage storage] referenceForURL:storageUrl]; + FIRStorageReference *storageRef; + if (storageUrl == nil ) { + storageRef = [[FIRStorage storage] reference]; + } else { + storageRef = [[FIRStorage storage] referenceForURL:storageUrl]; + } FIRStorageReference *fileRef = [storageRef child:path]; [fileRef downloadURLWithCompletion:^(NSURL * _Nullable URL, NSError * _Nullable error) { if (error != nil) { From f4bcfea81abb1c0d8fb37f02e912700ede340a4e Mon Sep 17 00:00:00 2001 From: Ari Lerner Date: Thu, 17 Nov 2016 20:24:38 -0500 Subject: [PATCH 31/62] WIP --- ios/Firestack/FirestackCloudMessaging.m | 55 ++++++++++++++----------- ios/Firestack/FirestackStorage.m | 1 + lib/modules/cloudmessaging.js | 24 ++++++++++- 3 files changed, 54 insertions(+), 26 deletions(-) diff --git a/ios/Firestack/FirestackCloudMessaging.m b/ios/Firestack/FirestackCloudMessaging.m index 0a71a64..ea8a346 100644 --- a/ios/Firestack/FirestackCloudMessaging.m +++ b/ios/Firestack/FirestackCloudMessaging.m @@ -68,34 +68,39 @@ + (void) setup:(UIApplication *) application selector:@selector(handleTokenRefresh) name:kFIRInstanceIDTokenRefreshNotification object: nil]; +} +#pragma mark Request permissions +- (void) requestPermissions(NSDictionary *)requestedPermissions + callback:(RCTResponseSenderBlock) callback +{ if (SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(@"9.0")) { - UIUserNotificationType allNotificationTypes = - (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge); - UIUserNotificationSettings *settings = - [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil]; - [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; -} else { - // iOS 10 or later - #if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 - UNAuthorizationOptions authOptions = - UNAuthorizationOptionAlert - | UNAuthorizationOptionSound - | UNAuthorizationOptionBadge; - [[UNUserNotificationCenter currentNotificationCenter] - requestAuthorizationWithOptions:authOptions - completionHandler:^(BOOL granted, NSError * _Nullable error) { - } - ]; - - // For iOS 10 display notification (sent via APNS) - [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self]; - // For iOS 10 data message (sent via FCM) - [[FIRMessaging messaging] setRemoteMessageDelegate:self]; - #endif -} + UIUserNotificationType allNotificationTypes = + (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge); + UIUserNotificationSettings *settings = + [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil]; + [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; + } else { + // iOS 10 or later + #if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + UNAuthorizationOptions authOptions = + UNAuthorizationOptionAlert + | UNAuthorizationOptionSound + | UNAuthorizationOptionBadge; + [[UNUserNotificationCenter currentNotificationCenter] + requestAuthorizationWithOptions:authOptions + completionHandler:^(BOOL granted, NSError * _Nullable error) { + } + ]; + + // For iOS 10 display notification (sent via APNS) + [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self]; + // For iOS 10 data message (sent via FCM) + [[FIRMessaging messaging] setRemoteMessageDelegate:self]; + #endif + } -[[UIApplication sharedApplication] registerForRemoteNotifications]; + [[UIApplication sharedApplication] registerForRemoteNotifications]; } #pragma mark callbacks diff --git a/ios/Firestack/FirestackStorage.m b/ios/Firestack/FirestackStorage.m index d88a19a..3e4511a 100644 --- a/ios/Firestack/FirestackStorage.m +++ b/ios/Firestack/FirestackStorage.m @@ -157,6 +157,7 @@ - (void) addUploadObservers:(FIRStorageUploadTask *) uploadTask case FIRStorageErrorCodeUnknown: // Unknown error occurred, inspect the server response [errProps setValue:@"Unknown error" forKey:@"description"]; + NSLog(@"Unknown error: %@", snapshot.error); break; } diff --git a/lib/modules/cloudmessaging.js b/lib/modules/cloudmessaging.js index a03a2ed..73b390b 100644 --- a/lib/modules/cloudmessaging.js +++ b/lib/modules/cloudmessaging.js @@ -1,12 +1,20 @@ -import {NativeModules, NativeEventEmitter} from 'react-native'; +import {Platform, NativeModules, NativeEventEmitter} from 'react-native'; const FirestackCloudMessaging = NativeModules.FirestackCloudMessaging; const FirestackCloudMessagingEvt = new NativeEventEmitter(FirestackCloudMessaging); import promisify from '../utils/promisify' import { Base, ReferenceBase } from './base' + +const defaultPermissions = { + 'badge': 1, + 'sound': 2, + 'alert': 3 +} export class CloudMessaging extends Base { constructor(firestack, options = {}) { super(firestack, options); + + this.requestedPermissions = Object.assign({}, defaultPermissions, options.permissions); } get namespace() { return 'firestack:cloudMessaging' @@ -16,6 +24,20 @@ export class CloudMessaging extends Base { return promisify('getToken', FirestackCloudMessaging)(); } + // Request FCM permissions + requestPermissions(requestedPermissions = {}) { + if (Platform.OS === 'ios') { + const mergedRequestedPermissions = Object.assign({}, + this.requestedPermissions, + requestedPermissions); + return promisify('requestPermissions', FirestackCloudMessaging)(mergedRequestedPermissions) + .then(perms => { + + return perms; + }); + } + } + sendMessage(details:Object = {}, type:string='local') { const methodName = `send${type == 'local' ? 'Local' : 'Remote'}` this.log.info('sendMessage', methodName, details); From 7cb0a0891394d33ee2319981cb321efec6535980 Mon Sep 17 00:00:00 2001 From: Elliot Hesp Date: Fri, 18 Nov 2016 09:13:00 +0000 Subject: [PATCH 32/62] Don't hard set Android play services version #134 --- android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/build.gradle b/android/build.gradle index a06d876..015c9a7 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -20,7 +20,7 @@ android { dependencies { compile 'com.facebook.react:react-native:0.20.+' - compile 'com.google.android.gms:play-services-base:9.8.0' + compile 'com.google.android.gms:play-services-base:+' compile 'com.google.firebase:firebase-core:9.8.0' compile 'com.google.firebase:firebase-auth:9.8.0' From aec484e544c16a16df8ca70200bbe5ceda11fea5 Mon Sep 17 00:00:00 2001 From: Spencer Thornock Date: Fri, 18 Nov 2016 07:07:27 -0700 Subject: [PATCH 33/62] fix missing downloadUrl property on ios --- ios/Firestack.xcodeproj/project.pbxproj | 2 ++ ios/Firestack/FirestackStorage.m | 1 + 2 files changed, 3 insertions(+) diff --git a/ios/Firestack.xcodeproj/project.pbxproj b/ios/Firestack.xcodeproj/project.pbxproj index ba05903..ee93f06 100644 --- a/ios/Firestack.xcodeproj/project.pbxproj +++ b/ios/Firestack.xcodeproj/project.pbxproj @@ -203,6 +203,7 @@ MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; + USER_HEADER_SEARCH_PATHS = "${PROJECT_DIR}/../../../ios/Pods/** $(SRCROOT)/../node_modules/react-native/React/** $(SRCROOT)/../../react-native/React/**"; }; name = Debug; }; @@ -237,6 +238,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + USER_HEADER_SEARCH_PATHS = "${PROJECT_DIR}/../../../ios/Pods/** $(SRCROOT)/../node_modules/react-native/React/** $(SRCROOT)/../../react-native/React/**"; VALIDATE_PRODUCT = YES; }; name = Release; diff --git a/ios/Firestack/FirestackStorage.m b/ios/Firestack/FirestackStorage.m index b87d394..a4ea18a 100644 --- a/ios/Firestack/FirestackStorage.m +++ b/ios/Firestack/FirestackStorage.m @@ -135,6 +135,7 @@ - (void) addUploadObservers:(FIRStorageUploadTask *) uploadTask @"fullPath": ref.fullPath, @"bucket": ref.bucket, @"name": ref.name, + @"downloadUrl": snapshot.metadata.downloadURLs[0].absoluteString, @"metadata": [snapshot.metadata dictionaryRepresentation] }; From fba26f87a21c0f2148dcdd3a3d53a26956c2d0bb Mon Sep 17 00:00:00 2001 From: Spencer Thornock Date: Fri, 18 Nov 2016 07:13:29 -0700 Subject: [PATCH 34/62] fix missing downloadUrl property on ios --- ios/Firestack.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/Firestack.xcodeproj/project.pbxproj b/ios/Firestack.xcodeproj/project.pbxproj index ee93f06..05df7d2 100644 --- a/ios/Firestack.xcodeproj/project.pbxproj +++ b/ios/Firestack.xcodeproj/project.pbxproj @@ -203,7 +203,7 @@ MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; - USER_HEADER_SEARCH_PATHS = "${PROJECT_DIR}/../../../ios/Pods/** $(SRCROOT)/../node_modules/react-native/React/** $(SRCROOT)/../../react-native/React/**"; + USER_HEADER_SEARCH_PATHS = ""; }; name = Debug; }; @@ -238,7 +238,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; - USER_HEADER_SEARCH_PATHS = "${PROJECT_DIR}/../../../ios/Pods/** $(SRCROOT)/../node_modules/react-native/React/** $(SRCROOT)/../../react-native/React/**"; + USER_HEADER_SEARCH_PATHS = ""; VALIDATE_PRODUCT = YES; }; name = Release; From bbfa9749c305e127be83e590e6ebf114b8ed1ccb Mon Sep 17 00:00:00 2001 From: Vyshakh Parakkat Date: Tue, 22 Nov 2016 21:21:19 +0400 Subject: [PATCH 35/62] Analytics parameter variable type fix for quantity, price and value. --- .../io/fullstack/firestack/FirestackAnalytics.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackAnalytics.java b/android/src/main/java/io/fullstack/firestack/FirestackAnalytics.java index ec67022..c4ee65d 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackAnalytics.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackAnalytics.java @@ -102,16 +102,16 @@ private Bundle makeEventBundle(final String name, final Map map) bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, val); } if (map.containsKey("quantity")) { - long val = (long) map.get("quantity"); - bundle.putLong(FirebaseAnalytics.Param.QUANTITY, val); + double val = (double) map.get("quantity"); + bundle.putDouble(FirebaseAnalytics.Param.QUANTITY, val); } if (map.containsKey("price")) { - long val = (long) map.get("price"); - bundle.putLong(FirebaseAnalytics.Param.PRICE, val); + double val = (double) map.get("price"); + bundle.putDouble(FirebaseAnalytics.Param.PRICE, val); } if (map.containsKey("value")) { - long val = (long) map.get("value"); - bundle.putLong(FirebaseAnalytics.Param.VALUE, val); + double val = (double) map.get("value"); + bundle.putDouble(FirebaseAnalytics.Param.VALUE, val); } if (map.containsKey("currency")) { String val = (String) map.get("currency"); @@ -171,7 +171,7 @@ private Bundle makeEventBundle(final String name, final Map map) } if (map.containsKey("shipping")) { double val = (double) map.get("shipping"); - bundle.putDouble(FirebaseAnalytics.Param.NUMBER_OF_PASSENGERS, val); + bundle.putDouble(FirebaseAnalytics.Param.SHIPPING, val); } if (map.containsKey("group_id")) { String val = (String) map.get("group_id"); From 64261f1ac9d8bf5c4a261d73ff5e9291566c63ea Mon Sep 17 00:00:00 2001 From: Chaitanya Bhagvan Date: Wed, 23 Nov 2016 17:36:44 +0530 Subject: [PATCH 36/62] getToken(true) will try to fetch token from server and fail if offline. --- android/src/main/java/io/fullstack/firestack/FirestackAuth.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java index 36dd584..b0743e2 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java @@ -518,7 +518,7 @@ public void userCallback(FirebaseUser passedUser, final Callback callback) { this.user = passedUser; } - this.user.getToken(true).addOnCompleteListener(new OnCompleteListener() { + this.user.getToken(false).addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { WritableMap msgMap = Arguments.createMap(); From 86907d5edae77a7f5dcb96937f4db49768c9f888 Mon Sep 17 00:00:00 2001 From: Chaitanya Bhagvan Date: Wed, 23 Nov 2016 17:37:13 +0530 Subject: [PATCH 37/62] Parity of response format --- ios/Firestack/FirestackAuth.m | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/ios/Firestack/FirestackAuth.m b/ios/Firestack/FirestackAuth.m index bcd0919..229c72a 100644 --- a/ios/Firestack/FirestackAuth.m +++ b/ios/Firestack/FirestackAuth.m @@ -29,7 +29,7 @@ @implementation FirestackAuth }; - [self sendJSEvent:AUTH_CHANGED_EVENT + [self sendJSEvent:AUTH_CHANGED_EVENT props: evt]; callBack(@[evt]); @@ -43,7 +43,7 @@ @implementation FirestackAuth @"eventName": AUTH_ANONYMOUS_ERROR_EVENT, @"errorMessage": ex.reason }; - + [self sendJSEvent:AUTH_ERROR_EVENT props:eventError]; NSLog(@"An exception occurred: %@", ex); @@ -186,9 +186,12 @@ @implementation FirestackAuth FIRUser *user = [FIRAuth auth].currentUser; if (user != nil) { - NSMutableDictionary *userProps = [self userPropsFromFIRUser:user]; - [userProps setValue: @((BOOL)true) forKey: @"authenticated"]; - callback(@[[NSNull null], userProps]); + NSDictionary *userProps = [self userPropsFromFIRUser:user]; + NSMutableDictionary *responseProps = @{ + @"authenticated": @((BOOL) true), + @"user": userProps + }; + callback(@[[NSNull null], responseProps]); } else { // No user is signed in. NSDictionary *err = @{ From 363ff1edffb81818d0df9ca973dd46c04ca72438 Mon Sep 17 00:00:00 2001 From: Chaitanya Bhagvan Date: Wed, 23 Nov 2016 17:41:43 +0530 Subject: [PATCH 38/62] Parity of response format --- ios/Firestack/FirestackAuth.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ios/Firestack/FirestackAuth.m b/ios/Firestack/FirestackAuth.m index 229c72a..fac9f41 100644 --- a/ios/Firestack/FirestackAuth.m +++ b/ios/Firestack/FirestackAuth.m @@ -187,7 +187,7 @@ @implementation FirestackAuth if (user != nil) { NSDictionary *userProps = [self userPropsFromFIRUser:user]; - NSMutableDictionary *responseProps = @{ + NSDictionary *responseProps = @{ @"authenticated": @((BOOL) true), @"user": userProps }; @@ -195,6 +195,7 @@ @implementation FirestackAuth } else { // No user is signed in. NSDictionary *err = @{ + @"authenticated": @((BOOL) false), @"user": @"No user logged in" }; callback(@[err]); From 03a2c8e94c0c820506bb4411afb9bae258781cfc Mon Sep 17 00:00:00 2001 From: Broda Noel Date: Fri, 25 Nov 2016 21:16:48 -0300 Subject: [PATCH 39/62] Add `invariant` dependencie --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index e611094..3903e46 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ }, "dependencies": { "bows": "^1.6.0", - "es6-symbol": "^3.1.0" + "es6-symbol": "^3.1.0", + "invariant": "^2.2.2" } } From 0f1b49fd61a93e531dde02a824274484705a4c84 Mon Sep 17 00:00:00 2001 From: Ari Lerner Date: Sat, 26 Nov 2016 15:54:07 -0800 Subject: [PATCH 40/62] Weird typo --- .../src/main/java/io/fullstack/firestack/FirestackAuth.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java index b0743e2..34e2bf5 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java @@ -639,6 +639,3 @@ private WritableMap getUserMap() { return userMap; } } -n userMap; - } -} From 17f41c7aef2530c53449c2c3f5f081b0b01fc306 Mon Sep 17 00:00:00 2001 From: Ari Lerner Date: Sat, 26 Nov 2016 22:11:55 -0800 Subject: [PATCH 41/62] Updated with call thread for signInWithProvider --- ios/Firestack/FirestackAuth.m | 2 ++ ios/Firestack/FirestackCloudMessaging.m | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ios/Firestack/FirestackAuth.m b/ios/Firestack/FirestackAuth.m index fac9f41..e058e2f 100644 --- a/ios/Firestack/FirestackAuth.m +++ b/ios/Firestack/FirestackAuth.m @@ -97,6 +97,8 @@ @implementation FirestackAuth callback(@[[NSNull null], userProps]); } else { NSLog(@"An error occurred: %@", [error localizedDescription]); + NSLog(@"[Error signInWithProvider]: %@", [error userInfo]); + NSLog(@"%@", [NSThread callStackSymbols]); // No user is signed in. NSDictionary *err = @{ @"error": @"No user signed in", diff --git a/ios/Firestack/FirestackCloudMessaging.m b/ios/Firestack/FirestackCloudMessaging.m index ea8a346..ca0f1ca 100644 --- a/ios/Firestack/FirestackCloudMessaging.m +++ b/ios/Firestack/FirestackCloudMessaging.m @@ -71,7 +71,7 @@ + (void) setup:(UIApplication *) application } #pragma mark Request permissions -- (void) requestPermissions(NSDictionary *)requestedPermissions +- (void) requestPermissions:(NSDictionary *)requestedPermissions callback:(RCTResponseSenderBlock) callback { if (SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(@"9.0")) { From ef4890a3a63162c2cd8590a087101686853fd26c Mon Sep 17 00:00:00 2001 From: Ari Lerner Date: Sun, 27 Nov 2016 00:07:21 -0800 Subject: [PATCH 42/62] Added Github auth and updated README --- README.md | 7 ++++++- ios/Firestack/FirestackAuth.m | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 84c3333..af50ed3 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,11 @@ For a detailed discussion of how Firestack works as well as how to contribute, c * Covers lots of awesome features of Firebase: * authentication * username and password - * social auth (implemented, but need to add providers) + * social auth (implemented in conjunction with [react-native-oauth](https://github.com/fullstackreact/react-native-oauth)) + * Facebook + * Github + * Google + * Twitter * storage handling * upload files * download urls @@ -25,6 +29,7 @@ For a detailed discussion of how Firestack works as well as how to contribute, c * presence out-of-the-box * analytics * Remote configuration + * FCM (in-progress) * Redux support built-in (but not required) * Android and iOS support * Community supported and professionally backed diff --git a/ios/Firestack/FirestackAuth.m b/ios/Firestack/FirestackAuth.m index e058e2f..13fed64 100644 --- a/ios/Firestack/FirestackAuth.m +++ b/ios/Firestack/FirestackAuth.m @@ -486,6 +486,9 @@ - (FIRAuthCredential *)getCredentialForProvider:(NSString *)provider } else if ([provider compare:@"google" options:NSCaseInsensitiveSearch] == NSOrderedSame) { credential = [FIRGoogleAuthProvider credentialWithIDToken:authToken accessToken:authTokenSecret]; + } else if ([provider compare:@"github" options:NSCaseInsensitiveSearch] == NSOrderedSame) { + credential = [FIRGitHubAuthProvider credentialWithIDToken:authToken + accessToken:authTokenSecret]; } else { NSLog(@"Provider not yet handled: %@", provider); } From 49afd2e31c320546b9dbd4d269142a3174943180 Mon Sep 17 00:00:00 2001 From: Ari Lerner Date: Thu, 1 Dec 2016 11:50:40 -0800 Subject: [PATCH 43/62] 2.3.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3903e46..a7ced67 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-firestack", - "version": "2.3.3", + "version": "2.3.4", "author": "Ari Lerner (https://fullstackreact.com)", "description": "A firebase v3 adapter", "main": "index", From dcabc4a0296795aacb7e248348eebf00792422b3 Mon Sep 17 00:00:00 2001 From: Ari Lerner Date: Sun, 4 Dec 2016 11:24:58 -0800 Subject: [PATCH 44/62] Oops. Fixes #3176 --- ios/Firestack/FirestackAuth.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ios/Firestack/FirestackAuth.m b/ios/Firestack/FirestackAuth.m index 13fed64..1ebccec 100644 --- a/ios/Firestack/FirestackAuth.m +++ b/ios/Firestack/FirestackAuth.m @@ -487,8 +487,7 @@ - (FIRAuthCredential *)getCredentialForProvider:(NSString *)provider credential = [FIRGoogleAuthProvider credentialWithIDToken:authToken accessToken:authTokenSecret]; } else if ([provider compare:@"github" options:NSCaseInsensitiveSearch] == NSOrderedSame) { - credential = [FIRGitHubAuthProvider credentialWithIDToken:authToken - accessToken:authTokenSecret]; + credential = [FIRGitHubAuthProvider credentialWithToken:authToken]; } else { NSLog(@"Provider not yet handled: %@", provider); } From bfa9ed31c8d9145b508d5e093fd90c59211b4500 Mon Sep 17 00:00:00 2001 From: Chaitanya Bhagvan Date: Mon, 5 Dec 2016 22:08:40 +0530 Subject: [PATCH 45/62] Change to Fix breaking window object --- lib/utils/window-or-global.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/utils/window-or-global.js b/lib/utils/window-or-global.js index 7b64020..c19a003 100644 --- a/lib/utils/window-or-global.js +++ b/lib/utils/window-or-global.js @@ -2,4 +2,4 @@ // https://github.com/purposeindustries/window-or-global module.exports = (typeof self === 'object' && self.self === self && self) || (typeof global === 'object' && global.global === global && global) || - {} \ No newline at end of file + this From 69f63ca2288e6a805f1ee4359de641b1fe3e731b Mon Sep 17 00:00:00 2001 From: YoYo Date: Wed, 7 Dec 2016 15:32:17 -0500 Subject: [PATCH 46/62] Readme link to firebase.google.com not firebase.com Firebase.com is the legacy console. Firebase.google.com is the latest firebase console. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af50ed3..5081297 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## Firestack -Firestack makes using the latest [Firebase](http://firebase.com) straight-forward. +Firestack makes using the latest [Firebase](https://firebase.google.com/) straight-forward. [![Gitter](https://badges.gitter.im/fullstackreact/react-native-firestack.svg)](https://gitter.im/fullstackreact/react-native-firestack?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) From cf71541841acc6bd175604919ffefbbb38bd7375 Mon Sep 17 00:00:00 2001 From: Brian Doyle Date: Wed, 7 Dec 2016 13:50:39 -0800 Subject: [PATCH 47/62] Typo --- .../src/main/java/io/fullstack/firestack/FirestackModule.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackModule.java b/android/src/main/java/io/fullstack/firestack/FirestackModule.java index ac2418f..2ec7972 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackModule.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackModule.java @@ -193,14 +193,14 @@ public void serverValue(@Nullable final Callback onComplete) { @Override public void onHostResume() { WritableMap params = Arguments.createMap(); - params.putBoolean("isForground", true); + params.putBoolean("isForeground", true); FirestackUtils.sendEvent(mReactContext, "FirestackAppState", params); } @Override public void onHostPause() { WritableMap params = Arguments.createMap(); - params.putBoolean("isForground", false); + params.putBoolean("isForeground", false); FirestackUtils.sendEvent(mReactContext, "FirestackAppState", params); } From 16659477403a38614e0018fa376e514bdbcd0d8b Mon Sep 17 00:00:00 2001 From: Brian Doyle Date: Wed, 7 Dec 2016 21:47:07 -0800 Subject: [PATCH 48/62] Added JS syntax highlighting --- README.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index af50ed3..c628748 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ To use Firestack, we'll need to have a development environment that includes the ### iOS (with cocoapods) -Unfortunately, due to AppStore restrictions, we currently do _not_ package Firebase libraries in with Firestack. However, the good news is we've automated the process (with many thanks to the Auth0 team for inspiration) of setting up with cocoapods. This will happen automatically upon linking the package with `react-native-cli`. +Unfortunately, due to AppStore restrictions, we currently do _not_ package Firebase libraries in with Firestack. However, the good news is we've automated the process (with many thanks to the Auth0 team for inspiration) of setting up with cocoapods. This will happen automatically upon linking the package with `react-native-cli`. **Remember to use the `ios/[YOUR APP NAME].xcworkspace` instead of the `ios/[YOUR APP NAME].xcproj` file from now on**. @@ -198,7 +198,7 @@ Each platform uses a different setup method after creating the project. ### iOS -After creating a Firebase project, click on the [Add Firebase to your iOS app](http://d.pr/i/3sEL.png) and follow the steps from there to add the configuration file. You do _not_ need to set up a cocoapods project (this is already done through firestack). Make sure not to forget the `Copy Files` phase in iOS. +After creating a Firebase project, click on the [Add Firebase to your iOS app](http://d.pr/i/3sEL.png) and follow the steps from there to add the configuration file. You do _not_ need to set up a cocoapods project (this is already done through firestack). Make sure not to forget the `Copy Files` phase in iOS. [Download the Firebase config file](https://support.google.com/firebase/answer/7015592) and place it in your app directory next to your app source code: @@ -206,7 +206,7 @@ After creating a Firebase project, click on the [Add Firebase to your iOS app](h Once you download the configuration file, make sure you place it in the root of your Xcode project. Every different Bundle ID (aka, even different project variants needs their own configuration file). -Lastly, due to some dependencies requirements, Firestack supports iOS versions 8.0 and up. Make sure to update the minimum version of your iOS app to `8.0`. +Lastly, due to some dependencies requirements, Firestack supports iOS versions 8.0 and up. Make sure to update the minimum version of your iOS app to `8.0`. ### Android @@ -369,7 +369,7 @@ We can use an external authentication provider, such as twitter/facebook for aut [Currently undergoing updates] ### socialLogin with custom Library -If you don't want to use [react-native-oauth](https://github.com/fullstackreact/react-native-oauth), you can use other library such as [react-native-facebook-login](https://github.com/magus/react-native-facebook-login). +If you don't want to use [react-native-oauth](https://github.com/fullstackreact/react-native-oauth), you can use other library such as [react-native-facebook-login](https://github.com/magus/react-native-facebook-login). ```javascript var {FBLogin, FBLoginManager} = require('react-native-facebook-login'); @@ -377,7 +377,7 @@ var {FBLogin, FBLoginManager} = require('react-native-facebook-login'); var Login = React.createClass({ render: function() { return ( - Note: this idea comes almost directory from [react-native-fs](https://github.com/johanneslumpe/react-native-fs), so we don't claim credit for coming up with this fantastic idea. +> Note: this idea comes almost directory from [react-native-fs](https://github.com/johanneslumpe/react-native-fs), so we don't claim credit for coming up with this fantastic idea. ### Realtime Database @@ -651,6 +651,7 @@ Ranking strategy Add a new record with timestamp using this solution: +```js firebaseApp.database.ref('posts').push().then((res) => { let newPostKey = res.key; firebaseApp.ServerValue.then(map => { @@ -673,15 +674,18 @@ firebaseApp.database.ref('posts').push().then((res) => { }) }) }) +``` Then retrieve the feed using this: +```js firebaseApp.database.ref('posts').orderByChild('timestamp').limitToLast(30).once('value') .then((snapshot) => { this.props.savePosts(snapshot.val()) const val = snapshot.val(); console.log(val); }) +``` #### DatabaseRef @@ -719,7 +723,7 @@ For handling offline operations, you can enable persistence by using the `setPer firestack.database.setPersistence(true); ``` -The database refs has a `keepSynced()` function to tell the firestack library to keep the data at the `ref` in sync. +The database refs has a `keepSynced()` function to tell the firestack library to keep the data at the `ref` in sync. ```javascript const ref = firestack.database @@ -799,7 +803,7 @@ Monitor token generation firestack.cloudMessaging.listenForTokenRefresh(function (token) { console.log('refresh device token', token); }); - + // remove listener firestack.cloudMessaging.unlistenForTokenRefresh(); ``` @@ -872,14 +876,14 @@ After the `npm` version is installed, you can either clone the repo directly int git clone https://github.com/fullstackreact/react-native-firestack.git ./node_modules/react-native-firestack ``` -Alternatively, you can clone the repo somewhere else and `rsync` the directory over to the `node_modules/` directory. +Alternatively, you can clone the repo somewhere else and `rsync` the directory over to the `node_modules/` directory. > This is the method I use as it allows me to separate the codebases: ```bash git clone https://github.com/fullstackreact/react-native-firestack.git \ ~/Development/react-native/mine/react-native-firestack/ - + ## And rsync rsync -avhW --delete \ --exclude='node_modules' \ From 5b7de35bb2a66294970ee8aa493f200bbcfd6791 Mon Sep 17 00:00:00 2001 From: Chaitanya Bhagvan Date: Fri, 23 Dec 2016 15:36:19 +0530 Subject: [PATCH 49/62] Maintain similar response format for getCurrentUser and signInWith* --- ios/Firestack/FirestackAuth.m | 37 +++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/ios/Firestack/FirestackAuth.m b/ios/Firestack/FirestackAuth.m index 1ebccec..6d45075 100644 --- a/ios/Firestack/FirestackAuth.m +++ b/ios/Firestack/FirestackAuth.m @@ -17,7 +17,7 @@ @implementation FirestackAuth RCT_EXPORT_MODULE(FirestackAuth); RCT_EXPORT_METHOD(signInAnonymously: - (RCTResponseSenderBlock) callBack) + (RCTResponseSenderBlock) callback) { @try { [[FIRAuth auth] signInAnonymouslyWithCompletion @@ -32,10 +32,14 @@ @implementation FirestackAuth [self sendJSEvent:AUTH_CHANGED_EVENT props: evt]; - callBack(@[evt]); + callback(@[evt]); } else { - NSDictionary *userProps = [self userPropsFromFIRUser:user]; - callBack(@[[NSNull null], userProps]); + NSDictionary *userProps = [self userPropsFromFIRUser:user]; + NSDictionary *responseProps = @{ + @"authenticated": @((BOOL) true), + @"user": userProps + }; + callback(@[[NSNull null], responseProps]); } }]; } @catch(NSException *ex) { @@ -47,7 +51,7 @@ @implementation FirestackAuth [self sendJSEvent:AUTH_ERROR_EVENT props:eventError]; NSLog(@"An exception occurred: %@", ex); - callBack(@[eventError]); + callback(@[eventError]); } } @@ -61,7 +65,11 @@ @implementation FirestackAuth if (user != nil) { NSDictionary *userProps = [self userPropsFromFIRUser:user]; - callback(@[[NSNull null], userProps]); + NSDictionary *responseProps = @{ + @"authenticated": @((BOOL) true), + @"user": userProps + }; + callback(@[[NSNull null], responseProps]); } else { NSDictionary *err = [FirestackErrors handleFirebaseError:AUTH_ERROR_EVENT @@ -94,7 +102,11 @@ @implementation FirestackAuth if (user != nil) { // User is signed in. NSDictionary *userProps = [self userPropsFromFIRUser:user]; - callback(@[[NSNull null], userProps]); + NSDictionary *responseProps = @{ + @"authenticated": @((BOOL) true), + @"user": userProps + }; + callback(@[[NSNull null], responseProps]); } else { NSLog(@"An error occurred: %@", [error localizedDescription]); NSLog(@"[Error signInWithProvider]: %@", [error userInfo]); @@ -146,7 +158,7 @@ @implementation FirestackAuth sendJSEvent:AUTH_CHANGED_EVENT props: @{ @"eventName": @"userTokenError", - @"authenticated": @((BOOL)true), + @"authenticated": @((BOOL)false), @"errorMessage": [error localizedFailureReason] }]; } else { @@ -236,10 +248,11 @@ @implementation FirestackAuth completion:^(FIRUser *user, NSError *error) { if (user != nil) { NSDictionary *userProps = [self userPropsFromFIRUser:user]; - - callback(@[[NSNull null], @{ - @"user": userProps - }]); + NSDictionary *responseProps = @{ + @"authenticated": @((BOOL) true), + @"user": userProps + }; + callback(@[[NSNull null], responseProps]); } else { NSDictionary *err = [FirestackErrors handleFirebaseError:@"signinError" From 47cc17eb7b4b692c95d2100c6c4f18b97c237010 Mon Sep 17 00:00:00 2001 From: Chaitanya Bhagvan Date: Fri, 23 Dec 2016 15:36:51 +0530 Subject: [PATCH 50/62] Remove anonymousUsercallback --- .../io/fullstack/firestack/FirestackAuth.java | 46 ++----------------- 1 file changed, 5 insertions(+), 41 deletions(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java index 34e2bf5..489ce5b 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java @@ -170,7 +170,7 @@ public void onComplete(@NonNull Task task) { if (task.isSuccessful()) { FirestackAuthModule.this.user = task.getResult().getUser(); - anonymousUserCallback(FirestackAuthModule.this.user, callback); + userCallback(FirestackAuthModule.this.user, callback); } else { // userErrorCallback(task, callback); } @@ -523,14 +523,15 @@ public void userCallback(FirebaseUser passedUser, final Callback callback) { public void onComplete(@NonNull Task task) { WritableMap msgMap = Arguments.createMap(); WritableMap userMap = getUserMap(); + boolean authenticated = false; if (FirestackAuthModule.this.user != null) { final String token = task.getResult().getToken(); userMap.putString("token", token); - userMap.putBoolean("anonymous", false); + authenticated = true; } msgMap.putMap("user", userMap); - msgMap.putBoolean("authenticated", true); + msgMap.putBoolean("authenticated", authenticated); callback.invoke(null, msgMap); } }).addOnFailureListener(new OnFailureListener() { @@ -541,43 +542,6 @@ public void onFailure(@NonNull Exception ex) { }); } - // TODO: Reduce to one method - public void anonymousUserCallback(FirebaseUser passedUser, final Callback callback) { - - if (passedUser == null) { - mAuth = FirebaseAuth.getInstance(); - this.user = mAuth.getCurrentUser(); - } else { - this.user = passedUser; - } - - this.user.getToken(true) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(@NonNull Task task) { - WritableMap msgMap = Arguments.createMap(); - WritableMap userMap = getUserMap(); - - if (FirestackAuthModule.this.user != null) { - final String token = task.getResult().getToken(); - - userMap.putString("token", token); - userMap.putBoolean("anonymous", true); - } - - msgMap.putMap("user", userMap); - - callback.invoke(null, msgMap); - } - }).addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@NonNull Exception ex) { - userExceptionCallback(ex, callback); - } - }); - } - - public void noUserCallback(final Callback callback) { WritableMap message = Arguments.createMap(); @@ -624,7 +588,7 @@ private WritableMap getUserMap() { userMap.putString("uid", uid); userMap.putString("providerId", provider); userMap.putBoolean("emailVerified", user.isEmailVerified()); - + userMap.putBoolean("anonymous", user.isAnonymous()); if (name != null) { userMap.putString("displayName", name); } From 04fb02d4236e52c68538b992b65cf932abc903b1 Mon Sep 17 00:00:00 2001 From: Ari Lerner Date: Sun, 4 Dec 2016 11:25:06 -0800 Subject: [PATCH 51/62] 2.3.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a7ced67..389045a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-firestack", - "version": "2.3.4", + "version": "2.3.5", "author": "Ari Lerner (https://fullstackreact.com)", "description": "A firebase v3 adapter", "main": "index", From a74513aa7f9ac175c1528115662145df51dab4cd Mon Sep 17 00:00:00 2001 From: Simon Henrotte Date: Sun, 1 Jan 2017 14:25:47 +0100 Subject: [PATCH 52/62] Fix example FBLogin in README.md The `.auth` was missing in the example for the Facebook Login. It throws an error if you copy/paste the example and run it `firestack.signInWithProvider is not a function`. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1957964..12ad9ac 100644 --- a/README.md +++ b/README.md @@ -382,7 +382,7 @@ var Login = React.createClass({ console.log("Logged in!"); console.log(data); let token = data.credentials.token - firestack.signInWithProvider('facebook', token, '') // facebook need only access token. + firestack.auth.signInWithProvider('facebook', token, '') // facebook need only access token. .then((user)=>{ console.log(user) }) From 4abe1ba10e29a8e604f92bbe81ca64df1d1116bc Mon Sep 17 00:00:00 2001 From: James Lin Date: Thu, 5 Jan 2017 10:44:26 +0800 Subject: [PATCH 53/62] update manual install doc in README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 12ad9ac..15aa469 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,12 @@ source 'https://github.com/CocoaPods/Specs.git' ].each do |lib| pod lib end + +target '[project name]' do +end + +# target '[project test name]' do +# end ``` Then you can run `(cd ios && pod install)` to get the pods opened. If you do use this route, remember to use the `.xcworkspace` file. From 46bfa956409d80f171d73ea38335ea9632b29593 Mon Sep 17 00:00:00 2001 From: beachcamp Date: Wed, 4 Jan 2017 20:03:04 -0800 Subject: [PATCH 54/62] Added signInWithProvider and reauthenticateWithCredentialForProvider functionality for Twitter --- .../io/fullstack/firestack/FirestackAuth.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java index 489ce5b..676b27f 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackAuth.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackAuth.java @@ -34,6 +34,7 @@ import com.google.firebase.auth.GetTokenResult; import com.google.firebase.auth.GoogleAuthProvider; import com.google.firebase.auth.FirebaseAuthException; +import com.google.firebase.auth.TwitterAuthProvider; class FirestackAuthModule extends ReactContextBaseJavaModule { private final int NO_CURRENT_USER = 100; @@ -153,6 +154,8 @@ public void signInWithProvider(final String provider, final String authToken, fi this.facebookLogin(authToken,callback); } else if (provider.equals("google")) { this.googleLogin(authToken,callback); + } else if (provider.equals("twitter")) { + this.twitterLogin(authToken,authSecret,callback); } else // TODO FirestackUtils.todoNote(TAG, "signInWithProvider", callback); @@ -215,6 +218,8 @@ public void reauthenticateWithCredentialForProvider(final String provider, final credential = FacebookAuthProvider.getCredential(authToken); } else if (provider.equals("google")) { credential = GoogleAuthProvider.getCredential(authToken, null); + } else if (provider.equals("twitter")) { + credential = TwitterAuthProvider.getCredential(authToken, authSecret); } else { // TODO: FirestackUtils.todoNote(TAG, "reauthenticateWithCredentialForProvider", callback); @@ -508,6 +513,30 @@ public void onFailure(@NonNull Exception ex) { }); } + @ReactMethod + public void twitterLogin(String Token, String Secret, final Callback callback) { + mAuth = FirebaseAuth.getInstance(); + + AuthCredential credential = TwitterAuthProvider.getCredential(Token, Secret); + mAuth.signInWithCredential(credential) + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + FirestackAuthModule.this.user = task.getResult().getUser(); + userCallback(FirestackAuthModule.this.user, callback); + }else{ + // userErrorCallback(task, callback); + } + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception ex) { + userExceptionCallback(ex, callback); + } + }); + } + // Internal helpers public void userCallback(FirebaseUser passedUser, final Callback callback) { From 854c3364c6d9f47584c726e049fa4210e63bed07 Mon Sep 17 00:00:00 2001 From: Friedjoff Trautwein Date: Thu, 5 Jan 2017 10:36:48 +0100 Subject: [PATCH 55/62] Only get reference from url if url string is set. --- .../src/main/java/io/fullstack/firestack/FirestackStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/src/main/java/io/fullstack/firestack/FirestackStorage.java b/android/src/main/java/io/fullstack/firestack/FirestackStorage.java index 210a1bd..414ceda 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackStorage.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackStorage.java @@ -146,7 +146,7 @@ public void onFailure(@NonNull Exception exception) { public void uploadFile(final String urlStr, final String name, final String filepath, final ReadableMap metadata, final Callback callback) { FirebaseStorage storage = FirebaseStorage.getInstance(); - StorageReference storageRef = storage.getReferenceFromUrl(urlStr); + StorageReference storageRef = urlStr!=null ? storage.getReferenceFromUrl(urlStr) : storage.getReference(); StorageReference fileRef = storageRef.child(name); Log.i(TAG, "From file: " + filepath + " to " + urlStr + " with name " + name); From 78f4452a1960615284744ffb4d641938db92dbc3 Mon Sep 17 00:00:00 2001 From: Ari Lerner Date: Mon, 9 Jan 2017 09:28:20 -0800 Subject: [PATCH 56/62] 2.3.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 389045a..316ba9c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-firestack", - "version": "2.3.5", + "version": "2.3.6", "author": "Ari Lerner (https://fullstackreact.com)", "description": "A firebase v3 adapter", "main": "index", From 011faa2e1986423a6ef2a7c2617dbd477aac0bbe Mon Sep 17 00:00:00 2001 From: Jonathan Chang Date: Tue, 10 Jan 2017 15:07:13 -0800 Subject: [PATCH 57/62] Remove reference to RCTReloadNotification This observer just calls reloadFirestack, neither of which I think is needed (anymore?). --- ios/Firestack/Firestack.h | 5 ++-- ios/Firestack/Firestack.m | 56 +++++++++++++++------------------------ 2 files changed, 23 insertions(+), 38 deletions(-) diff --git a/ios/Firestack/Firestack.h b/ios/Firestack/Firestack.h index ffb5cc3..e148a80 100644 --- a/ios/Firestack/Firestack.h +++ b/ios/Firestack/Firestack.h @@ -16,10 +16,9 @@ } // + (void) registerForNotification:(NSString *) typeStr andToken:(NSData *)deviceToken; -+ (void) setup:(UIApplication *) application ++ (void) setup:(UIApplication *) application withLaunchOptions: (NSDictionary *) launchOptions; -+ (void) reloadFirestack; + (id) sharedInstance; - (void) debugLog:(NSString *)title @@ -35,4 +34,4 @@ withLaunchOptions: (NSDictionary *) launchOptions; @end -#endif \ No newline at end of file +#endif diff --git a/ios/Firestack/Firestack.m b/ios/Firestack/Firestack.m index 284f38b..717311d 100644 --- a/ios/Firestack/Firestack.m +++ b/ios/Firestack/Firestack.m @@ -24,14 +24,14 @@ - (void)dealloc } // TODO: Implement -+ (void) setup:(UIApplication *) application ++ (void) setup:(UIApplication *) application withLaunchOptions: (NSDictionary *) launchOptions { NSLog(@"Called setup for firestack with application"); - + dispatch_once(&onceToken, ^{ [application registerForRemoteNotifications]; - + [[NSNotificationCenter defaultCenter] postNotificationName:kFirestackInitialized object:nil]; @@ -42,7 +42,7 @@ - (id) init { self = [super init]; if (self != nil) { - NSLog(@"Setting up Firestace instance"); + NSLog(@"Setting up Firestack instance"); [Firestack initializeFirestack:self]; } return self; @@ -52,12 +52,7 @@ + (void) initializeFirestack:(Firestack *) instance { dispatch_once(&onceToken, ^{ _sharedInstance = instance; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(reloadFirestack) - name:RCTReloadNotification - object:nil]; - + [[NSNotificationCenter defaultCenter] postNotificationName:kFirestackInitialized object:nil]; @@ -70,15 +65,6 @@ + (instancetype) sharedInstance return _sharedInstance; } -+ (void) reloadFirestack -{ - // Reloading firestack - onceToken = 0; // not sure if this is a good idea or a bad idea... - [[Firestack sharedInstance] debugLog:@"Firestack" - msg:@"Reloading firestack"]; - _sharedInstance = nil; -} - - (FIRApp *) firebaseApp { return [FIRApp defaultApp]; @@ -101,7 +87,7 @@ - (FIRApp *) firebaseApp // Are we debugging, yo? self.debug = [opts valueForKey:@"debug"] != nil ? YES : NO; NSLog(@"options passed into configureWithOptions: %@", [opts valueForKey:@"debug"]); - + NSDictionary *keyMapping = @{ @"GOOGLE_APP_ID": @[ @"appId", @@ -158,18 +144,18 @@ - (FIRApp *) firebaseApp ] }; NSArray *optionKeys = [keyMapping allKeys]; - + NSMutableDictionary *props; - + NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"]; - + if ([[NSFileManager defaultManager] fileExistsAtPath:plistPath]) { // If the Firebase plist is included props = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath]; } else { props = [[NSMutableDictionary alloc] initWithCapacity:[optionKeys count]]; } - + // Bundle ID either from options OR from the main bundle NSString *bundleID; if ([opts valueForKey:@"bundleID"]) { @@ -178,7 +164,7 @@ - (FIRApp *) firebaseApp bundleID = [[NSBundle mainBundle] bundleIdentifier]; } [props setValue:bundleID forKey:@"BUNDLE_ID"]; - + // Prefer the user configuration options over the default options for (int i=0; i < [optionKeys count]; i++) { // Traditional for loop here @@ -189,9 +175,9 @@ - (FIRApp *) firebaseApp NSString *value = [opts valueForKey:key]; [props setValue:value forKey:key]; } - + NSArray *possibleNames = [keyMapping objectForKey:key]; - + for (NSString *name in possibleNames) { if ([opts valueForKey:name] != nil) { // The user passed this option in @@ -205,7 +191,7 @@ - (FIRApp *) firebaseApp NSLog(@"An error occurred: %@", err); } } - + @try { if (self.debug) { NSLog(@"props ->: %@", props); @@ -220,7 +206,7 @@ - (FIRApp *) firebaseApp NSLog(@"STORAGE_BUCKET: %@", [props valueForKey:@"STORAGE_BUCKET"]); NSLog(@"DEEP_LINK_SCHEME: %@", [props valueForKey:@"DEEP_LINK_SCHEME"]); } - + FIROptions *finalOptions = [[FIROptions alloc] initWithGoogleAppID:[props valueForKey:@"GOOGLE_APP_ID"] bundleID:[props valueForKey:@"BUNDLE_ID"] @@ -232,16 +218,16 @@ - (FIRApp *) firebaseApp databaseURL:[props valueForKey:@"DATABASE_URL"] storageBucket:[props valueForKey:@"STORAGE_BUCKET"] deepLinkURLScheme:[props valueForKey:@"DEEP_LINK_SCHEME"]]; - + // Save configuration option // NSDictionary *cfg = [self getConfig]; // [cfg setValuesForKeysWithDictionary:props]; - + // if (!self.configured) { - + if ([FIRApp defaultApp] == NULL) { [FIRApp configureWithOptions:finalOptions]; - } + } [Firestack initializeFirestack:self]; callback(@[[NSNull null], props]); } @@ -382,8 +368,8 @@ - (void) debugLog:(NSString *)title // Not sure how to get away from this... yet - (NSArray *)supportedEvents { return @[ - INITIALIZED_EVENT, - DEBUG_EVENT, + INITIALIZED_EVENT, + DEBUG_EVENT, AUTH_CHANGED_EVENT]; } From 7c723081fd60b65528f3b326539929fc2e297f66 Mon Sep 17 00:00:00 2001 From: Ari Lerner Date: Wed, 11 Jan 2017 14:51:43 -0800 Subject: [PATCH 58/62] 2.3.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 316ba9c..4fd6fa8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-firestack", - "version": "2.3.6", + "version": "2.3.7", "author": "Ari Lerner (https://fullstackreact.com)", "description": "A firebase v3 adapter", "main": "index", From 17b870dc2d178f6bca3a19feeb1b0cd1f406f089 Mon Sep 17 00:00:00 2001 From: Ari Lerner Date: Thu, 12 Jan 2017 13:57:46 -0800 Subject: [PATCH 59/62] 2.3.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4fd6fa8..a84919f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-firestack", - "version": "2.3.7", + "version": "2.3.8", "author": "Ari Lerner (https://fullstackreact.com)", "description": "A firebase v3 adapter", "main": "index", From d9babd50e9be34fd372b746a4e3909644ee234fc Mon Sep 17 00:00:00 2001 From: Ari Lerner Date: Thu, 12 Jan 2017 23:18:15 -0800 Subject: [PATCH 60/62] Updated with small changes to fix blocking Android bug --- android/build.gradle | 12 ++++++------ .../io/fullstack/firestack/FirestackPackage.java | 4 ++-- .../io/fullstack/firestack/FirestackStorage.java | 8 ++++++-- lib/modules/storage.js | 2 ++ 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 015c9a7..a0fd688 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -22,11 +22,11 @@ dependencies { compile 'com.facebook.react:react-native:0.20.+' compile 'com.google.android.gms:play-services-base:+' - compile 'com.google.firebase:firebase-core:9.8.0' - compile 'com.google.firebase:firebase-auth:9.8.0' - compile 'com.google.firebase:firebase-analytics:9.8.0' - compile 'com.google.firebase:firebase-database:9.8.0' - compile 'com.google.firebase:firebase-storage:9.8.0' - compile 'com.google.firebase:firebase-messaging:9.8.0' + compile 'com.google.firebase:firebase-core:10.0.1' + compile 'com.google.firebase:firebase-auth:10.0.1' + compile 'com.google.firebase:firebase-analytics:10.0.1' + compile 'com.google.firebase:firebase-database:10.0.1' + compile 'com.google.firebase:firebase-storage:10.0.1' + compile 'com.google.firebase:firebase-messaging:10.0.1' } diff --git a/android/src/main/java/io/fullstack/firestack/FirestackPackage.java b/android/src/main/java/io/fullstack/firestack/FirestackPackage.java index ea5927d..b84edb0 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackPackage.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackPackage.java @@ -29,8 +29,8 @@ public List createNativeModules(ReactApplicationContext reactConte modules.add(new FirestackAuthModule(reactContext)); modules.add(new FirestackDatabaseModule(reactContext)); modules.add(new FirestackAnalyticsModule(reactContext)); - modules.add(new FirestackStorageModule(reactContext)); - modules.add(new FirestackCloudMessaging(reactContext)); + modules.add(new FirestackStorage(reactContext)); + // modules.add(new FirestackCloudMessaging(reactContext)); return modules; } diff --git a/android/src/main/java/io/fullstack/firestack/FirestackStorage.java b/android/src/main/java/io/fullstack/firestack/FirestackStorage.java index 414ceda..691aa48 100644 --- a/android/src/main/java/io/fullstack/firestack/FirestackStorage.java +++ b/android/src/main/java/io/fullstack/firestack/FirestackStorage.java @@ -43,7 +43,7 @@ import com.google.firebase.storage.StorageMetadata; import com.google.firebase.storage.StorageReference; -class FirestackStorageModule extends ReactContextBaseJavaModule { +class FirestackStorage extends ReactContextBaseJavaModule { private static final String TAG = "FirestackStorage"; private static final String DocumentDirectoryPath = "DOCUMENT_DIRECTORY_PATH"; @@ -53,6 +53,7 @@ class FirestackStorageModule extends ReactContextBaseJavaModule { private static final String TemporaryDirectoryPath = "TEMPORARY_DIRECTORY_PATH"; private static final String CachesDirectoryPath = "CACHES_DIRECTORY_PATH"; private static final String DocumentDirectory = "DOCUMENT_DIRECTORY_PATH"; + private static final String BundlePath = "MAIN_BUNDLE_PATH"; private static final String FileTypeRegular = "FILETYPE_REGULAR"; private static final String FileTypeDirectory = "FILETYPE_DIRECTORY"; @@ -62,8 +63,10 @@ class FirestackStorageModule extends ReactContextBaseJavaModule { private ReactContext mReactContext; private FirebaseApp app; - public FirestackStorageModule(ReactApplicationContext reactContext) { + public FirestackStorage(ReactApplicationContext reactContext) { super(reactContext); + + Log.d(TAG, "Attaching FirestackStorage"); this.context = reactContext; mReactContext = reactContext; @@ -279,6 +282,7 @@ public Map getConstants() { constants.put(CachesDirectoryPath, this.getReactApplicationContext().getCacheDir().getAbsolutePath()); constants.put(FileTypeRegular, 0); constants.put(FileTypeDirectory, 1); + constants.put(BundlePath, null); File externalStorageDirectory = Environment.getExternalStorageDirectory(); if (externalStorageDirectory != null) { diff --git a/lib/modules/storage.js b/lib/modules/storage.js index 6e5f46a..3434415 100644 --- a/lib/modules/storage.js +++ b/lib/modules/storage.js @@ -6,6 +6,8 @@ const FirestackStorageEvt = new NativeEventEmitter(FirestackStorage); import promisify from '../utils/promisify' import { Base, ReferenceBase } from './base' +console.log('FirestackStorage ---->', FirestackStorage); + class StorageRef extends ReferenceBase { constructor(storage, path) { super(storage.firestack, path); From 4937825658763873028466fe7e29f25707e54bd7 Mon Sep 17 00:00:00 2001 From: Nate Murray Date: Thu, 16 Feb 2017 08:43:01 -0600 Subject: [PATCH 61/62] Added Fullstack React Book to the README --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 15aa469..3fc41c4 100644 --- a/README.md +++ b/README.md @@ -916,3 +916,15 @@ The following is left to be done: - [ ] Add JS api - [ ] Move to use swift (cleaner syntax) - [ ] TODO: Finish Facebook integration + +# Fullstack React Book + + +Fullstack React Book + + +This repo was written and is maintained by the [Fullstack React](https://fullstackreact.com) team. + +If you're looking to learn React, there's no faster way than by spending a few hours with the [Fullstack React book](https://fullstackreact.com). + +
From b8b130752f1c09a7487d0498391e330c591d0f23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind?= Date: Wed, 31 May 2017 17:36:27 +0100 Subject: [PATCH 62/62] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 3fc41c4..79bbdfe 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +---- +### This library is no longer maintained, use at your own risk or please [seek alternatives on npm](https://www.npmjs.com/search?q=react+native+firebase). +---- + ## Firestack Firestack makes using the latest [Firebase](https://firebase.google.com/) straight-forward.