Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
amandeepmittal committed Mar 20, 2019
0 parents commit a304c0c
Show file tree
Hide file tree
Showing 15 changed files with 9,109 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .expo/packager-info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"devToolsPort": 19002,
"expoServerPort": null,
"packagerPort": null,
"packagerPid": null,
"expoServerNgrokUrl": null,
"packagerNgrokUrl": null,
"ngrokPid": null,
"webpackServerPort": null
}
7 changes: 7 additions & 0 deletions .expo/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"hostType": "lan",
"lanType": "ip",
"dev": true,
"minify": false,
"urlRandomness": "da-33u"
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
config/firebaseSDK.js
Build a Chat app with Firebase and React Native.md
1 change: 1 addition & 0 deletions .watchmanconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
10 changes: 10 additions & 0 deletions App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { createStackNavigator } from 'react-navigation';
import Login from './components/Login';
import Signup from './components/Signup';
import Chat from './components/Chat';

export default createStackNavigator({
Login: { screen: Login },
Signup: { screen: Signup },
Chat: { screen: Chat }
});
29 changes: 29 additions & 0 deletions app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"expo": {
"name": "RN + Firebase Chat App",
"slug": "RNfirebase-chat",
"privacy": "public",
"sdkVersion": "32.0.0",
"platforms": [
"ios",
"android"
],
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"updates": {
"fallbackToCacheTimeout": 0
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true
}
}
}
Binary file added assets/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/splash.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
};
};
45 changes: 45 additions & 0 deletions components/Chat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import { GiftedChat } from 'react-native-gifted-chat'; // 0.3.0

import firebaseSDK from '../config/firebaseSDK';

export default class Chat extends React.Component {
static navigationOptions = ({ navigation }) => ({
title: (navigation.state.params || {}).name || 'Chat!'
});

state = {
messages: []
};

get user() {
return {
name: this.props.navigation.state.params.name,
email: this.props.navigation.state.params.email,
avatar: this.props.navigation.state.params.avatar,
id: firebaseSDK.uid,
_id: firebaseSDK.uid
};
}

render() {
return (
<GiftedChat
messages={this.state.messages}
onSend={firebaseSDK.send}
user={this.user}
/>
);
}

componentDidMount() {
firebaseSDK.refOn(message =>
this.setState(previousState => ({
messages: GiftedChat.append(previousState.messages, message)
}))
);
}
componentWillUnmount() {
firebaseSDK.refOff();
}
}
98 changes: 98 additions & 0 deletions components/Login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import React from 'react';
import { StyleSheet, Text, TextInput, View, Button } from 'react-native';
import firebaseSDK from '../config/firebaseSDK';

export default class Login extends React.Component {
static navigationOptions = {
title: 'RN + Firebase Chat App'
};

state = {
name: 'Alice',
email: 'test@live.com',
password: '123456',
avatar: ''
};

onPressLogin = async () => {
const user = {
name: this.state.name,
email: this.state.email,
password: this.state.password,
avatar: this.state.avatar
};

const response = firebaseSDK.login(
user,
this.loginSuccess,
this.loginFailed
);
};

loginSuccess = () => {
console.log('login successful, navigate to chat.');
this.props.navigation.navigate('Chat', {
name: this.state.name,
email: this.state.email,
avatar: this.state.avatar
});
};

loginFailed = () => {
alert('Login failure. Please tried again.');
};

onChangeTextEmail = email => this.setState({ email });
onChangeTextPassword = password => this.setState({ password });

render() {
return (
<View>
<Text style={styles.title}>Email:</Text>
<TextInput
style={styles.nameInput}
placeHolder="test3@gmail.com"
onChangeText={this.onChangeTextEmail}
value={this.state.email}
/>
<Text style={styles.title}>Password:</Text>
<TextInput
style={styles.nameInput}
onChangeText={this.onChangeTextPassword}
value={this.state.password}
/>
<Button
title="Login"
style={styles.buttonText}
onPress={this.onPressLogin}
/>

<Button
title="Signup"
style={styles.buttonText}
onPress={() => this.props.navigation.navigate('Signup')}
/>
</View>
);
}
}

const styles = StyleSheet.create({
title: {
marginTop: 16,
marginLeft: 16,
fontSize: 16
},
nameInput: {
height: 16 * 2,
margin: 16,
paddingHorizontal: 16,
borderColor: '#111111',
borderWidth: 1,
fontSize: 16
},
buttonText: {
marginLeft: 16,
fontSize: 42
}
});
144 changes: 144 additions & 0 deletions components/Signup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import React from 'react';
import { ImagePicker, Permissions } from 'expo';
import {
StyleSheet,
Text,
TextInput,
View,
Button,
ImageEditor
} from 'react-native';

import firebaseSDK from '../config/firebaseSDK';

export default class Signup extends React.Component {
state = {
name: 'no name',
email: 'test@live.com',
password: '123456',
avatar: ''
};

onPressCreate = async () => {
try {
const user = {
name: this.state.name,
email: this.state.email,
password: this.state.password
};
await firebaseSDK.createAccount(user);
} catch ({ message }) {
console.log('create account failed. catch error:' + message);
}
};

onChangeTextEmail = email => this.setState({ email });
onChangeTextPassword = password => this.setState({ password });
onChangeTextName = name => this.setState({ name });

onImageUpload = async () => {
const { status: cameraRollPerm } = await Permissions.askAsync(
Permissions.CAMERA_ROLL
);
try {
// only if user allows permission to camera roll
if (cameraRollPerm === 'granted') {
let pickerResult = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
aspect: [4, 3]
});
console.log(
'ready to upload... pickerResult json:' + JSON.stringify(pickerResult)
);

var wantedMaxSize = 150;
var rawheight = pickerResult.height;
var rawwidth = pickerResult.width;
var ratio = rawwidth / rawheight;
var wantedwidth = wantedMaxSize;
var wantedheight = wantedMaxSize / ratio;
// check vertical or horizontal
if (rawheight > rawwidth) {
wantedwidth = wantedMaxSize * ratio;
wantedheight = wantedMaxSize;
}
let resizedUri = await new Promise((resolve, reject) => {
ImageEditor.cropImage(
pickerResult.uri,
{
offset: { x: 0, y: 0 },
size: { width: pickerResult.width, height: pickerResult.height },
displaySize: { width: wantedwidth, height: wantedheight },
resizeMode: 'contain'
},
uri => resolve(uri),
() => reject()
);
});
let uploadUrl = await firebaseSDK.uploadImage(resizedUri);
this.setState({ avatar: uploadUrl });
await firebaseSDK.updateAvatar(uploadUrl);
}
} catch (err) {
console.log('onImageUpload error:' + err.message);
alert('Upload image error:' + err.message);
}
};

render() {
return (
<View>
<Text style={styles.title}>Email:</Text>
<TextInput
style={styles.nameInput}
placeHolder="test@live.com"
onChangeText={this.onChangeTextEmail}
value={this.state.email}
/>
<Text style={styles.title}>Password:</Text>
<TextInput
style={styles.nameInput}
onChangeText={this.onChangeTextPassword}
value={this.state.password}
/>
<Text style={styles.title}>Name:</Text>
<TextInput
style={styles.nameInput}
onChangeText={this.onChangeTextName}
value={this.state.name}
/>
<Button
title="Signup"
style={styles.buttonText}
onPress={this.onPressCreate}
/>
<Button
title="Upload Avatar"
style={styles.buttonText}
onPress={this.onImageUpload}
/>
</View>
);
}
}

const offset = 16;
const styles = StyleSheet.create({
title: {
marginTop: offset,
marginLeft: offset,
fontSize: offset
},
nameInput: {
height: offset * 2,
margin: offset,
paddingHorizontal: offset,
borderColor: '#111111',
borderWidth: 1,
fontSize: offset
},
buttonText: {
marginLeft: offset,
fontSize: 42
}
});
27 changes: 27 additions & 0 deletions config/example.firebaseSDK.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// after adding keys
// rename this file to "firebaseSDK.js"

import firebase from 'firebase';

class FirebaseSDK {
constructor() {
if (!firebase.apps.length) {
firebase.initializeApp({
apiKey: '<your-api-key>',
authDomain: '<your-auth-domain>',
databaseURL: 'https://<your-db-url>.firebaseio.com',
projectId: '<your-project-id>',
storageBucket: '<your-storage-bucket>.appspot.com',
messagingSenderId: '<your-sender-id>'
});
}
}
login = async (user, success_callback, failed_callback) => {
await firebase
.auth()
.signInWithEmailAndPassword(user.email, user.password)
.then(success_callback, failed_callback);
};
}
const firebaseSDK = new FirebaseSDK();
export default firebaseSDK;
Loading

0 comments on commit a304c0c

Please sign in to comment.