Uygulamamız kullanıcının isminin alındığı ve mesajlaşmanın yapıldığı iki ekrandan oluşacak. Bu bölümde oluşturulan dosyalar ve ilişkileri anlatılacaktır.
Öncelikle App.Js dosyasını oluşturalım.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import { createAppContainer, createStackNavigator } from 'react-navigation'; //Ekranlarımız import Main from './components/Main'; import Chat from './components/Chat'; //navigator ayarları const AppNavigator = createStackNavigator({ Main: { screen: Main }, Chat: { screen: Chat }, }); const AppContainer = createAppContainer(AppNavigator); //main sayfanın başlaması için export edilmeli export default AppContainer |
Components klasöründeki Main kullanıcı isim girişi iken Chat mesajlaşma bölümü içindir. Navigation, daha önceki derslerde anlattığımız react-navigation üzerine kurulmuştur. Bir Stack Navigator kullanarak Main ekranına tekrar dönüş sağlanmıştır.
Main.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import React from 'react'; import { StyleSheet, Text, TextInput,TouchableOpacity, View} from 'react-native'; class Main extends React.Component { static navigationOptions = { title: 'Chat Uygulaması', }; state = { name: '', }; onPress = () => this.props.navigation.navigate('Chat', { name: this.state.name }); onChangeText = name => this.setState({ name }); render() { return ( <View> <Text style={styles.title}>İsim girin:</Text> <TextInput style={styles.nameInput} placeHolder="İsim" onChangeText={this.onChangeText} value={this.state.name} /> <TouchableOpacity onPress={this.onPress}> <Text style={styles.buttonText}>Giriş</Text> </TouchableOpacity> </View> ); } } const offset = 24; const styles = StyleSheet.create({ title: { marginTop: offset, marginLeft: offset, fontSize: offset, }, nameInput: { height: offset * 2, margin: offset, paddingHorizontal: offset, borderColor: '#111111', borderWidth: 1, }, buttonText: { marginLeft: offset, fontSize: offset, }, }); export default Main; |
Main’de TouchableOpacity bileşenine tıklandığında kullanıcı ismi (name) state üzerinden bir sonraki sayfaya taşınır. this.props.navigation.navigate fonksiyonu içindeki name: this.state.name komutu bir sonraki sayfaya state’in taşınmasını sağlar. (Bu yönetim zor olduğu için Redux konusu anlatılmıştır, uygulama karmaşıklaştıkça Redux önerilir.)
Chat.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
import React from 'react'; import { GiftedChat } from 'react-native-gifted-chat'; // chat için UI import Fire from '../Fire'; type Props = { name?: string, }; class Chat extends React.Component<Props> { static navigationOptions = ({ navigation }) => ({ title: (navigation.state.params || {}).name || 'Chat!', }); state = { messages: [], }; get user() { return { name: this.props.navigation.state.params.name, _id: Fire.shared.uid, }; } render() { return ( <GiftedChat messages={this.state.messages} onSend={Fire.shared.send} user={this.user} /> ); } componentDidMount() { Fire.shared.on(message => this.setState(previousState => ({ messages: GiftedChat.append(previousState.messages, message), })) ); } componentWillUnmount() { Fire.shared.off(); } } export default Chat; |
Chat.js, görsel bir chat bileşeni için react-native-gifted-chat ve mesajları taşıma için Fire.js (Firebase işlemlerini içeriyor) kullanır. Kullanıcı ismi state içinden alınırken Firebase tarafındaki kullanıcı Fire.shared.uid üzerinden alınır.
<GiftedChat messages={this.state.messages} onSend={Fire.shared.send} user={this.user} /> bileşeninin aldığı parametreler sayesinde chat ortamı hızlıca hazırlanır. message’lar state üzerinde tutulur. Gönderim işlemi (onSend) Firebase üzerinden yapılır. user için ise bir önceki sayfadan alınan değer kullanılır.
Fire.js: Firebase bağlantısı ve haberleşmesi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
//Firebase ayarları import firebase from 'firebase'; class Fire { constructor() { this.init(); this.observeAuth(); } init = () => firebase.initializeApp({ apiKey: "AIz..............................VI", authDomain: "chatuygulamasi-22939.firebaseapp.com", databaseURL: "https://chatuygulamasi-22939.firebaseio.com", projectId: "chatuygulamasi-22939", storageBucket: "chatuygulamasi-22939.appspot.com", messagingSenderId: "18.........95" }); observeAuth = () => firebase.auth().onAuthStateChanged(this.onAuthStateChanged); onAuthStateChanged = user => { if (!user) { try { firebase.auth().signInAnonymously(); } catch ({ message }) { alert(message); } } }; get uid() { return (firebase.auth().currentUser || {}).uid; } get ref() { return firebase.database().ref('messages'); } parse = snapshot => { const { timestamp: numberStamp, text, user } = snapshot.val(); const { key: _id } = snapshot; const timestamp = new Date(numberStamp); const message = { _id, timestamp, text, user, }; return message; }; on = callback => this.ref .limitToLast(20) .on('child_added', snapshot => callback(this.parse(snapshot))); get timestamp() { return firebase.database.ServerValue.TIMESTAMP; } // mesajları sunucu tarafına göndermek send = messages => { for (let i = 0; i < messages.length; i++) { const { text, user } = messages[i]; const message = { text, user, timestamp: this.timestamp, }; this.append(message); } }; append = message => this.ref.push(message); //sunucu tarafı ile iletişimi kapatma off() { this.ref.off(); } } Fire.shared = new Fire(); export default Fire; |
init fonksiyonunda firebase bağlantı ayarları yapılmaktadır. Bu ayarları firabase web uygulaması üzerinden web geliştirici için config ayarlarından alabilirsiniz. Kullanıcının sisteme bağlanması observeAuth üzerinden yapılır. callback ile mesajlar alınıp parse edilirken send ile de mesajlar firebase gönderilmektedir.