Skip to content

Commit 423e733

Browse files
committed
Merge branch 'master' into download
* master: Updated README installation instructions Updates to Podfile to include use_frameworks Updated README with removing build phases (no longer necessary) Adding missing user info mapping to getUserMap fixing NPE after Database#off Formatting updates for README added instructions for running on the master branch Updates Added protection around user on android to ensure it is not null on auth actions Fixed provider google on Android (was missing) Implement android ServerValue.TIMESTAMP Cast firebase long's to doubles Update README.md Update Android status Allow removal of specific callbacks from query listeners 2.3.2 Removed modules from FirestackAnalytics
2 parents 7968560 + 6c2230b commit 423e733

13 files changed

+182
-86
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,4 @@ android/gradlew
5454
android/gradlew.bat
5555
android/gradle/
5656
.idea
57+
.idea

README.md

+63-23
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ For a detailed discussion of how Firestack works, check out our [contribution gu
3131
* Intended on being as drop-dead simple as possible
3232
* And so much more
3333

34+
## Example app
35+
36+
We have a working application example available in at [fullstackreact/FirestackApp](https://github.com/fullstackreact/FirestackApp). Check it out for more details about how to use Firestack.
37+
3438
## Why?
3539

3640
Firebase is awesome and it's combination with the Google Cloud Platform makes it super awesome. Sadly, the latest version of Firebase requires the `window` object. That's where Firestack comes in! Firestack provides a really thin layer that sits on top of the native Firebase SDKs and attempts to use the JavaScript library as much as possible rather than reinventing the wheel.
@@ -41,8 +45,7 @@ Getting `react-native-firestack` up and running in your app should be a 2 step p
4145

4246
1. Install the `npm` package
4347
2. Link the project with `react-native link react-native-firestack`
44-
3. Modify the _Build Phases_ for iOS like it says below.
45-
4. To ensure Android is setup, check your `MainApplication.java` for the `FirestackPackage()` line.
48+
3. To ensure Android is setup, check your `MainApplication.java` for the `FirestackPackage()` line.
4649

4750
Those steps in more detail:
4851

@@ -82,19 +85,15 @@ If you prefer not to use `rnpm`, we can manually link the package together with
8285

8386
![Firebase.xcodeproj in Libraries listing](http://d.pr/i/19ktP.png)
8487

85-
3. In the project's "Build Settings" tab in your app's target, add `libFirestack.a` to the list of `Link Binary with Libraries`
86-
87-
![Linking binaries](http://d.pr/i/1cHgs.png)
88-
89-
4. Ensure that the `Build Settings` of the `Firestack.xcodeproj` project is ticked to _All_ and it's `Header Search Paths` include both of the following paths _and_ are set to _recursive_:
88+
3. Ensure that the `Build Settings` of the `Firestack.xcodeproj` project is ticked to _All_ and it's `Header Search Paths` include both of the following paths _and_ are set to _recursive_:
9089

9190
1. `$(SRCROOT)/../../react-native/React`
9291
2. `$(SRCROOT)/../node_modules/react-native/React`
9392
3. `${PROJECT_DIR}/../../../ios/Pods`
9493

9594
![Recursive paths](http://d.pr/i/1hAr1.png)
9695

97-
5. Setting up cocoapods
96+
4. Setting up cocoapods
9897

9998
Since we're dependent upon cocoapods (or at least the Firebase libraries being available at the root project -- i.e. your application), we have to make them available for Firestack to find them.
10099

@@ -323,7 +322,7 @@ firestack.createUserWithEmail('[email protected]', '123456')
323322
To sign a user in with their email and password, use the `signInWithEmail()` function. It accepts two parameters, the user's email and password:
324323

325324
```javascript
326-
firestack.signInWithEmail('[email protected]', '123456')
325+
firestack.auth.signInWithEmail('[email protected]', '123456')
327326
.then((user) => {
328327
console.log('User successfully logged in', user)
329328
})
@@ -592,23 +591,33 @@ storageRef.downloadUrl()
592591

593592
### Realtime Database
594593

595-
#### database attribute
596-
597594
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.
598595

596+
#### DatabaseRef
597+
598+
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.
599+
600+
#### Example
601+
599602
```javascript
600-
firestack.database
601-
.ref(LIST_KEY)
602-
.on('value', snapshot => {
603-
if (snapshot.val()) {
604-
console.log('The list was updated');
605-
}
606-
});
607-
```
608603

609-
#### DatabaseRef
604+
function handleValueChange(snapshot) {
605+
if (snapshot.val()) {
606+
console.log('The list was updated');
607+
}
608+
}
609+
610+
const LIST_KEY = 'path/to/data';
611+
firestack.database.ref(LIST_KEY).on('value', handleValueChange);
610612

611-
Firestack attempts to provide the same API as the JS Firebase library for both Android and iOS platforms.
613+
// Calling `.off` with a reference to the callback function will only remove that specific listener.
614+
// This is useful if multiple components are listening and unlistening to the same ref path.
615+
firestack.database.ref(LIST_KEY).off('value', handleValueChange);
616+
617+
// Calling `.off` without passing the callback function will remove *all* 'value' listeners for that ref
618+
firestack.database.ref(LIST_KEY).off('value');
619+
620+
```
612621

613622
// TODO: Finish documenting
614623

@@ -757,6 +766,37 @@ firestack.off('listenForAuth');
757766

758767
Firestack provides a built-in way to connect your Redux app using the `FirestackModule` export from Firestack.
759768

769+
## Running with the `master` branch
770+
771+
Most of our work is committed to the master branch. If you want to run the bleeding-edge version of Firestack, you'll need to follow these instructions.
772+
773+
Since `react-native` doesn't like symlinks, we need to clone the raw repository into our `node_modules/` manually. First, in order to tell `react-native` we are using the package `react-native-firestack`, make sure to install the `npm` version:
774+
775+
```bash
776+
npm install --save react-native-firestack
777+
```
778+
779+
After the `npm` version is installed, you can either clone the repo directly into our `node_modules/` directory:
780+
781+
```bash
782+
git clone https://github.com/fullstackreact/react-native-firestack.git ./node_modules/react-native-firestack
783+
```
784+
785+
Alternatively, you can clone the repo somewhere else and `rsync` the directory over to the `node_modules/` directory.
786+
787+
> This is the method I use as it allows me to separate the codebases:
788+
789+
```bash
790+
git clone https://github.com/fullstackreact/react-native-firestack.git \
791+
~/Development/react-native/mine/react-native-firestack/
792+
793+
## And rsync
794+
rsync -avhW --delete \
795+
--exclude='node_modules' \
796+
--exclude='.git' \
797+
~/Development/react-native/mine/react-native-firestack/ \
798+
./node_modules/react-native-firestack/
799+
```
760800

761801
## Contributing
762802

@@ -774,8 +814,8 @@ The following is left to be done:
774814

775815
- [x] Complete FirebaseModule functionality
776816
- [ ] Document FirebaseModule
777-
- [ ] Add Android support
778-
- in progress
817+
- [X] Add Android support
818+
- auth/analytics/database/storage/presence are feature-complete. remoteconfig/messaging are mostly-there.
779819
- [x] Add Cloud Messaging
780820
- [ ] Add JS api
781821
- [ ] Move to use swift (cleaner syntax)

android/.idea/runConfigurations.xml

-12
This file was deleted.

android/build.gradle

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ android {
99
targetSdkVersion 23
1010
versionCode 1
1111
versionName "1.0"
12+
multiDexEnabled true
1213
}
1314
buildTypes {
1415
release {
@@ -19,6 +20,8 @@ android {
1920

2021
dependencies {
2122
compile 'com.facebook.react:react-native:0.20.+'
23+
compile 'com.google.android.gms:play-services-base:9.6.1'
24+
2225
compile 'com.google.firebase:firebase-core:9.6.0'
2326
compile 'com.google.firebase:firebase-auth:9.6.0'
2427
compile 'com.google.firebase:firebase-analytics:9.6.0'

android/src/main/java/io/fullstack/firestack/FirestackAuth.java

+67-22
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ public void onComplete(@NonNull Task<AuthResult> task) {
138138
public void signInWithProvider(final String provider, final String authToken, final String authSecret, final Callback callback) {
139139
if (provider.equals("facebook")) {
140140
this.facebookLogin(authToken,callback);
141+
} else if (provider.equals("google")) {
142+
this.googleLogin(authToken,callback);
141143
} else
142144
// TODO
143145
FirestackUtils.todoNote(TAG, "signInWithProvider", callback);
@@ -155,7 +157,7 @@ public void onComplete(@NonNull Task<AuthResult> task) {
155157

156158
if (task.isSuccessful()) {
157159
user = task.getResult().getUser();
158-
userCallback(user, callback);
160+
anonymousUserCallback(user, callback);
159161
}else{
160162
userErrorCallback(task, callback);
161163
}
@@ -354,6 +356,7 @@ public void onComplete(@NonNull Task<Void> task) {
354356
@ReactMethod
355357
public void signOut(final Callback callback) {
356358
FirebaseAuth.getInstance().signOut();
359+
user = null;
357360

358361
WritableMap resp = Arguments.createMap();
359362
resp.putString("status", "complete");
@@ -426,29 +429,55 @@ public void userCallback(FirebaseUser passedUser, final Callback onComplete) {
426429
user.getToken(true).addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
427430
@Override
428431
public void onComplete(@NonNull Task<GetTokenResult> task) {
432+
WritableMap msgMap = Arguments.createMap();
429433
WritableMap userMap = Arguments.createMap();
430-
final String name = user.getDisplayName();
431-
final String token = task.getResult().getToken();
432-
final String email = user.getEmail();
433-
final String uid = user.getUid();
434-
final String provider = user.getProviderId();
435-
final Uri photoUrl = user.getPhotoUrl();
436-
437-
userMap.putString("name", name);
438-
userMap.putString("token", token);
439-
userMap.putString("email", email);
440-
userMap.putString("uid", uid);
441-
userMap.putString("provider", provider);
442-
443-
if (photoUrl!=null) {
444-
userMap.putString("photoUrl",photoUrl.toString());
434+
435+
if (user != null) {
436+
final String token = task.getResult().getToken();
437+
438+
userMap.putString("token", token);
439+
userMap.putBoolean("anonymous", false);
445440
}
446441

447-
onComplete.invoke(null, userMap);
442+
msgMap.putMap("user", userMap);
443+
444+
onComplete.invoke(null, msgMap);
448445
}
449446
});
450447
}
451448

449+
// TODO: Reduce to one method
450+
public void anonymousUserCallback(FirebaseUser passedUser, final Callback onComplete) {
451+
WritableMap userMap = getUserMap();
452+
453+
if (passedUser == null) {
454+
mAuth = FirebaseAuth.getInstance();
455+
final FirebaseUser user = mAuth.getCurrentUser();
456+
} else {
457+
final FirebaseUser user = passedUser;
458+
}
459+
460+
user.getToken(true).addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
461+
@Override
462+
public void onComplete(@NonNull Task<GetTokenResult> task) {
463+
WritableMap msgMap = Arguments.createMap();
464+
WritableMap userMap = Arguments.createMap();
465+
466+
if (user != null) {
467+
final String token = task.getResult().getToken();
468+
469+
userMap.putString("token", token);
470+
userMap.putBoolean("anonymous", true);
471+
}
472+
473+
msgMap.putMap("user", userMap);
474+
475+
onComplete.invoke(null, msgMap);
476+
}
477+
});
478+
}
479+
480+
452481
public void noUserCallback(final Callback callback) {
453482
WritableMap message = Arguments.createMap();
454483

@@ -473,12 +502,28 @@ private WritableMap getUserMap() {
473502

474503
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
475504

476-
userMap.putString("email", user.getEmail());
477-
userMap.putString("uid", user.getUid());
478-
userMap.putString("provider", user.getProviderId());
505+
if (user != null) {
506+
final String email = user.getEmail();
507+
final String uid = user.getUid();
508+
final String provider = user.getProviderId();
509+
final String name = user.getDisplayName();
510+
final Uri photoUrl = user.getPhotoUrl();
511+
512+
userMap.putString("email", email);
513+
userMap.putString("uid", uid);
514+
userMap.putString("providerId", provider);
515+
516+
if (name != null) {
517+
userMap.putString("name", name);
518+
}
519+
520+
if (photoUrl != null) {
521+
userMap.putString("photoUrl", photoUrl.toString());
522+
}
523+
} else {
524+
userMap.putString("msg", "no user");
525+
}
479526

480527
return userMap;
481528
}
482-
483-
484529
}

android/src/main/java/io/fullstack/firestack/FirestackDatabase.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -682,8 +682,8 @@ private <Any> Any castSnapshotValue(DataSnapshot snapshot) {
682682
case "java.lang.Boolean":
683683
data.putBoolean(child.getKey(), (Boolean) castedChild);
684684
break;
685-
case "java.lang.Integer":
686-
data.putInt(child.getKey(), (Integer) castedChild);
685+
case "java.lang.Long":
686+
data.putDouble(child.getKey(), (Long) castedChild);
687687
break;
688688
case "java.lang.Double":
689689
data.putDouble(child.getKey(), (Double) castedChild);
@@ -704,7 +704,7 @@ private <Any> Any castSnapshotValue(DataSnapshot snapshot) {
704704
case "java.lang.Boolean":
705705
return (Any)((Boolean) snapshot.getValue());
706706
case "java.lang.Long":
707-
return (Any)((Integer)(((Long) snapshot.getValue()).intValue()));
707+
return (Any) ((Long) snapshot.getValue());
708708
case "java.lang.Double":
709709
return (Any)((Double) snapshot.getValue());
710710
case "java.lang.String":

android/src/main/java/io/fullstack/firestack/FirestackModule.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import android.content.Context;
44
import android.util.Log;
5+
import java.util.Map;
56
import android.support.annotation.NonNull;
67
import android.support.annotation.Nullable;
78

@@ -178,9 +179,13 @@ public String setKeyOrDefault(
178179

179180
@ReactMethod
180181
public void serverValue(@Nullable final Callback onComplete) {
182+
WritableMap timestampMap = Arguments.createMap();
183+
for (Map.Entry<String, String> entry : ServerValue.TIMESTAMP.entrySet()) {
184+
timestampMap.putString(entry.getKey(), entry.getValue());
185+
}
186+
181187
WritableMap map = Arguments.createMap();
182-
// TODO
183-
map.putString("TIMESTAMP", "ServerValue.TIMESTAMP");
188+
map.putMap("TIMESTAMP", timestampMap);
184189
onComplete.invoke(null, map);
185190
}
186191

0 commit comments

Comments
 (0)