Antes de mais nada, iremos usar partes de dois tutoriais que já disponibilizei.
1) Siga o tutorial do link abaixo a partir da parte que contém os prints da tela do Android Studio. Esse passo requer que você já tenha seu projeto criado e rodando.
Login com Google usando React Native
2) Siga todo o tutorial do link abaixo. No final vou disponibilizar as modificações feitas no arquivo deste tutorial, mas é importante seguir o passo a passo.
Login com LinkedIn usando React Native
Acesse o console do firebase da sua conta, abra seu projeto criado especialmente para este tutorial. No menu lateral, acesse Database, em seu Cloud Firestore crie uma coleção chamada groupChat.
Outra coisa importante para essa parte do firebase é que você adicione um app android e outro app web ao seu projeto. A imagem abaixo mostra onde fica essa opção.
Ao selecionar android, irá aparecer uma outra página para que você possa preencher os dados necessários, onde a chave SHA1 obtida no passo 1 será preenchida. Ao final é disponibilizado um arquivos chamado google-services.json que você precisa salvar na pasta app que fica dentro da pasta android de seu projeto. A imagem abaixo mostra como é a página em questão.
Ao selecionar web, irá abrir uma página para que você preencha alguns dados e o mais importante nessa parte é copiar os dados que serão disponibilizados pelo firebase ao final. Copie e salve os dados disponibilizados. A imagem abaixo mostra como é a página.
Em seu projeto, crie um arquivo chamado firebaseSDK.js e dentro dele você vai colocar os dados obtidos no passo anterior. Abaixo um exemplo do arquivo:
import firebase from '@react-native-firebase/app';
const config = {
apiKey: '*****',
authDomain: '*****',
databaseURL: '*****',
projectId: '*****',
storageBucket: '******',
messagingSenderId: '*****',
appId: '******',
};
let Firebase;
if (!firebase.apps.length) {
Firebase = firebase.initializeApp(config);
}
export default Firebase;
Iremos precisar de duas dependências para a parte do Firebase em nosso projeto. A instalação e configuração de cada uma é mostrada nos links que irei disponibilizar abaixo:
1) https://invertase.io/oss/react-native-firebase/quick-start/existing-project
2) https://invertase.io/oss/react-native-firebase/v6/firestore/quick-start
Observação: No passo 1 acima, há uma configuração para android e iOS, recomendo que dê uma olhada para que tudo ocorra bem. Caso use apenas android, como é no meu caso, siga apenas a parte de configuração para android.
Neste tutorial também é usado outra dependência, ela será útil para a navegação usada no tutorial. Navegue até a raiz do seu projeto pelo terminal e digite o comando abaixo:
$ yarn add react-navigation
Para a parte do chat iremos usar uma lib bastante famosa para esta finalidade. A lib se chama Gifted Chat e para adicionar a mesma em seu projeto, acesse a raiz do seu projeto pelo terminal e digite o comando abaixo:
$ yarn add react-native-gifted-chat
Agora irei disponibilizar o código dos arquivos referentes ao Login e Chat em si. Abaixo o código de Login com LinkedIn com algumas alterações para este tutorial. Neste tutorial o chamei de Main.
Main.js
import React, {useState, useEffect} from 'react';
import {StyleSheet, View, Text, Image} from 'react-native';
import LinkedInModal from 'react-native-linkedin';
import axios from 'axios';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
justifyContent: 'center',
alignItems: 'center',
},
});
export default function Main({navigation}) {
const [token, setToken] = useState('');
const [info, setInfo] = useState();
const [loading, setLoading] = useState(true);
const instance = axios.create({
baseURL: 'https://api.linkedin.com/v2',
headers: {
Authorization: 'Bearer ' + token,
},
});
async function getInfo() {
await instance
.get(
'/me?projection=(id,firstName,lastName,profilePicture(displayImage~:playableStreams))',
)
.then(response => {
setInfo(response.data);
setLoading(false);
navigation.navigate('Chat', {
userChat: response.data,
});
})
.catch(error => console.log(error));
}
useEffect(() => {
getInfo();
}, [token]);
const renderData = info && (
<>
<Text>{info.firstName.localized.pt_BR}</Text>
<Text>{info.lastName.localized.pt_BR}</Text>
<Image
source={{
uri:
info.profilePicture['displayImage~'].elements[3]['identifiers'][0][
'identifier'
],
}}
style={{
width: 200,
height: 200,
left: 'auto',
right: 'auto',
justifyContent: 'center',
}}
/>
</>
);
return (
<View style={styles.container}>
<LinkedInModal
clientID="******"
clientSecret="*****"
redirectUri="https://api.linkedin.com/v2/me"
onSuccess={token => setToken(token.access_token)}
onError={error => console.log(error)}
areaTouchText={{top: 20, bottom: 20, left: 150, right: 150}}
/>
{loading && <Text>{'Loading...'}</Text>}
{renderData}
</View>
);
}
Main.navigationOptions = {
title: 'Main',
};
Agora o código do Chat.js
import React, {useState, useEffect} from 'react';
import {View, Text} from 'react-native';
import firestore from '@react-native-firebase/firestore';
import {GiftedChat, Bubble} from 'react-native-gifted-chat';
function Chat(props) {
const [user, setUser] = useState(props.navigation.getParam('userChat'));
const [messages, setMessages] = useState([]);
useEffect(() => {
console.log(user);
const db = firestore();
db.collection('groupChat')
.orderBy('createdAt', 'desc')
.onSnapshot(function(doc) {
let receivedMessages = [];
doc.docs.map(doc => {
receivedMessages.push({
_id: doc.id,
...doc.data(),
});
});
setMessages(GiftedChat.append(messages, receivedMessages));
});
}, [user]);
function onSend([messages]) {
firestore()
.collection('groupChat')
.add(messages);
}
function renderBubble(props) {
return (
<View>
<Text style={{left: 90}}>{props.currentMessage.user.name}</Text>
<Bubble
{...props}
/>
</View>
);
}
return (
<GiftedChat
dateFormat={'DD-MM-YYYY'}
timeFormat={'h:mm'}
renderBubble={renderBubble}
messages={messages}
onSend={messages => onSend(messages)}
user={{
id: user.id,
name: user.firstName.localized.pt_BR,
}}
/>
);
}
Chat.navigationOptions = {
title: 'Chat',
};
export default Chat;
E por último o código de rotas
routes.js
import {createAppContainer, createSwitchNavigator} from 'react-navigation';
import Main from './Main';
import Chat from './Chat';
const Routes = createAppContainer(
createSwitchNavigator({
Main: Main,
Chat: Chat,
}),
);
export default Routes;
O Chat em questão funciona como uma sala única para várias pessoas. Abaixo segue imagens do app em funcionamento e como deve ficar:
É isto! Esse é bem mais trabalhoso, mas creio que deu para passar +/- como é e espero que consigam seguir o tutorial e funcione direitinho :) se surgir dúvidas é só comentar. Até a próxima :)
Top comments (3)
Quando há dois dispositivos com horários diferentes, as mensagens não são enviadas em ordem. O aparelho com o horário mais adiantado no seu celular sempre tem a última mensagem e o aparelho que tem o horário atrasado sempre tem o horário antes da mensagem do outro aparelho, mesmo enviando depois do outro aparelho.
Como fazer com que as mensagens estejam em ordem independente do tempo em diferentes dispositivos?
Da pra utilizar esse método para criar um chat privado?
Dá sim :)