Merge commit '49d29b53f21e530f5c918e472db93ee856947426'

This commit is contained in:
Chris Bianca
2017-10-03 10:33:18 +01:00
27 changed files with 1998 additions and 971 deletions

View File

@@ -1,5 +1,16 @@
{
"presets": [
"react-native"
]
],
"env": {
"development": {
"plugins": [
["istanbul", {
"include": [
"**/firebase/**.js"
]
}]
]
}
}
}

View File

@@ -1,15 +1,80 @@
package com.reactnativefirebasedemo;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import com.facebook.react.ReactActivity;
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "ReactNativeFirebaseDemo";
public static final int PERMISSION_REQ_CODE = 1234;
public static final int OVERLAY_PERMISSION_REQ_CODE = 1235;
String[] perms = {
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE"
};
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "ReactNativeFirebaseDemo";
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkWindowPerms();
}
public void checkWindowPerms() {
// Checking if device version > 22 and we need to use new permission model
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
// Checking if we can draw window overlay
if (!Settings.canDrawOverlays(this)) {
// Requesting permission for window overlay(needed for all react-native apps)
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
}
for (String perm : perms) {
// Checking each permission and if denied then requesting permissions
if (checkSelfPermission(perm) == PackageManager.PERMISSION_DENIED) {
requestPermissions(perms, PERMISSION_REQ_CODE);
break;
}
}
}
}
// Window overlay permission intent result
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
checkWindowPerms();
}
}
// Permission results
@Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults) {
switch (permsRequestCode) {
case PERMISSION_REQ_CODE:
// example how to get result of permissions requests (there can be more then one permission dialog)
// boolean readAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED;
// boolean writeAccepted = grantResults[1]==PackageManager.PERMISSION_GRANTED;
// checking permissions to prevent situation when user denied some permission
checkWindowPerms();
break;
}
}
}

2005
tests/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -32,8 +32,9 @@
"js-beautify": "^1.6.11",
"lodash.groupby": "^4.6.0",
"lodash.some": "^4.6.0",
"react": "16.0.0-alpha.6",
"react-native": "^0.44.0",
"react": "16.0.0-alpha.12",
"react-native": "^0.48.4",
"react-test-renderer": "16.0.0-alpha.12",
"react-native-simple-toast": "0.0.5",
"react-native-vector-icons": "^4.0.0",
"react-navigation": "^1.0.0-beta.9",
@@ -51,6 +52,7 @@
"babel-eslint": "^7.1.1",
"babel-jest": "19.0.0",
"babel-plugin-flow-react-proptypes": "^0.21.0",
"babel-plugin-istanbul": "^4.1.5",
"babel-preset-react-native": "1.9.1",
"colors": "^1.1.2",
"eslint": "^3.16.1",
@@ -60,7 +62,6 @@
"eslint-plugin-jsx-a11y": "^4.0.0",
"eslint-plugin-react": "^6.10.0",
"jest": "19.0.2",
"react-test-renderer": "~15.4.1",
"redux-immutable-state-invariant": "^1.2.4"
},
"jest": {

249
tests/src/phone-auth.js Normal file
View File

@@ -0,0 +1,249 @@
import React, { Component } from 'react';
import { View, Button, Text, TextInput, Image, ActivityIndicator, Platform } from 'react-native';
import fb from './firebase';
const firebase = fb.native;
const imageUrl = 'https://www.shareicon.net/data/512x512/2016/07/19/798524_sms_512x512.png';
export default class PhoneAuth extends Component {
static getDefaultState() {
return {
message: '',
error: '',
codeInput: '',
phoneNumber: '+44',
auto: Platform.OS === 'android',
autoVerifyCountDown: 0,
sent: false,
started: false,
user: null,
};
}
constructor(props) {
super(props);
this.timeout = 20;
this._autoVerifyInterval = null;
this.state = PhoneAuth.getDefaultState();
}
_tick() {
this.setState({
autoVerifyCountDown: this.state.autoVerifyCountDown - 1,
});
}
/**
* Called when confirm code is pressed - we should have the code and verificationId now in state.
*/
afterVerify = () => {
const { codeInput, verificationId } = this.state;
const credential = firebase.auth.PhoneAuthProvider.credential(verificationId, codeInput);
// TODO do something with credential for example:
firebase.auth()
.signInWithCredential(credential)
.then((user) => {
console.log('PHONE AUTH USER ->>>>>', user.toJSON());
this.setState({ user: user.toJSON() });
}).catch(console.error);
};
signIn = () => {
const { phoneNumber } = this.state;
this.setState({ message: 'Sending code ...', error: '', started: true, autoVerifyCountDown: this.timeout }, () => {
firebase.auth()
.verifyPhoneNumber(phoneNumber)
.on('state_changed', (phoneAuthSnapshot) => {
console.log(phoneAuthSnapshot);
switch (phoneAuthSnapshot.state) {
case firebase.auth.PhoneAuthState.CODE_SENT: // or 'sent'
// update state with code sent and if android start a interval timer
// for auto verify - to provide visual feedback
this.setState({
sent: true,
message: 'Code Sent!',
verificationId: phoneAuthSnapshot.verificationId,
autoVerifyCountDown: this.timeout,
}, () => {
if (this.state.auto) {
this._autoVerifyInterval = setInterval(this._tick.bind(this), 1000);
}
});
break;
case firebase.auth.PhoneAuthState.ERROR: // or 'error'
// restart the phone flow again on error
clearInterval(this._autoVerifyInterval);
this.setState({
...PhoneAuth.getDefaultState(),
error: phoneAuthSnapshot.error.message,
});
break;
// ---------------------
// ANDROID ONLY EVENTS
// ---------------------
case firebase.auth.PhoneAuthState.AUTO_VERIFY_TIMEOUT: // or 'timeout'
clearInterval(this._autoVerifyInterval);
this.setState({
sent: true,
auto: false,
verificationId: phoneAuthSnapshot.verificationId,
});
break;
case firebase.auth.PhoneAuthState.AUTO_VERIFIED: // or 'verified'
clearInterval(this._autoVerifyInterval);
this.setState({
sent: true,
codeInput: phoneAuthSnapshot.code,
verificationId: phoneAuthSnapshot.verificationId,
});
break;
default:
// will never get here - just for linting
}
});
});
};
renderInputPhoneNumber() {
const { phoneNumber } = this.state;
return (
<View style={{ flex: 1 }}>
<Text>Enter phone number:</Text>
<TextInput
autoFocus
style={{ height: 40, marginTop: 15, marginBottom: 15 }}
onChangeText={value => this.setState({ phoneNumber: value })}
placeholder={'Phone number ... '}
value={phoneNumber}
/>
<Button title="Begin Verification" color="green" onPress={this.signIn} />
</View>
);
}
renderSendingCode() {
const { phoneNumber } = this.state;
return (
<View style={{ paddingBottom: 15 }}>
<Text
style={{ paddingBottom: 25 }}
>
{`Sending verification code to '${phoneNumber}'.`}
</Text>
<ActivityIndicator animating style={{ padding: 50 }} size={'large'} />
</View>
);
}
renderAutoVerifyProgress() {
const { autoVerifyCountDown, started, error, sent, phoneNumber } = this.state;
if (!sent && started && !error.length) {
return this.renderSendingCode();
}
return (
<View style={{ padding: 0 }}>
<Text
style={{ paddingBottom: 25 }}
>
{`Verification code has been successfully sent to '${phoneNumber}'.`}
</Text>
<Text
style={{ marginBottom: 25 }}
>
{`We'll now attempt to automatically verify the code for you. This will timeout in ${autoVerifyCountDown} seconds.`}
</Text>
<Button
style={{ paddingTop: 25 }} title="I have a code already" color="green"
onPress={() => this.setState({ auto: false })}
/>
</View>
);
}
renderError() {
const { error } = this.state;
return (
<View style={{ padding: 10, borderRadius: 5, margin: 10, backgroundColor: 'rgb(255,0,0)' }}>
<Text
style={{ color: '#fff' }}
>
{error}
</Text>
</View>
);
}
render() {
const { started, error, codeInput, sent, auto, user } = this.state;
return (
<View style={{ flex: 1, backgroundColor: user ? 'rgb(0, 200, 0)' : '#fff' }}>
<View
style={{
padding: 5,
justifyContent: 'center',
alignItems: 'center',
flex: 1,
}}
>
<Image source={{ uri: imageUrl }} style={{ width: 128, height: 128, marginTop: 25, marginBottom: 15 }} />
<Text style={{ fontSize: 25, marginBottom: 20 }}>Phone Auth Example</Text>
{error && error.length ? this.renderError() : null}
{!started && !sent ? this.renderInputPhoneNumber() : null}
{started && auto && !codeInput.length ? this.renderAutoVerifyProgress() : null}
{!user && started && sent && (codeInput.length || !auto) ? (
<View style={{ marginTop: 15 }}>
<Text>Enter verification code below:</Text>
<TextInput
autoFocus
style={{ height: 40, marginTop: 15, marginBottom: 15 }}
onChangeText={value => this.setState({ codeInput: value })}
placeholder={'Code ... '}
value={codeInput}
/>
<Button title="Confirm Code" color="#841584" onPress={this.afterVerify} />
</View>
) : null}
{user ? (
<View style={{ marginTop: 15 }}>
<Text>{`Signed in with new user id: '${user.uid}'`}</Text>
</View>
) : null}
</View>
</View>
);
}
}
/*
{ user ? (
<View
style={{
padding: 15,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#77dd77',
flex: 1,
}}
>
<Image source={{ uri: successImageUri }} style={{ width: 100, height: 100, marginBottom: 25 }} />
<Text style={{ fontSize: 25 }}>Signed In!</Text>
<Text>{JSON.stringify(user)}</Text>
</View>
) : null}
*/
// Example usage if handling here and not in optionalCompleteCb:
// const { verificationId, code } = phoneAuthSnapshot;
// const credential = firebase.auth.PhoneAuthProvider.credential(verificationId, code);
// Do something with your new credential, e.g.:
// firebase.auth().signInWithCredential(credential);
// firebase.auth().linkWithCredential(credential);
// etc ...

View File

@@ -11,6 +11,10 @@ import performance from './perf';
import admob from './admob';
import firestore from './firestore';
window.getCoverage = function getCoverage() {
return (JSON.stringify(global.__coverage__));
};
const testSuiteInstances = [
admob,
analytics,