I'm creating a react native chat app and I cant get the username in the messages
// retrieve the messages from the Backend
loadMessages(callback) {
this.messagesRef = firebase.database().ref("messages");
this.messagesRef.off();
const onReceive = data => {
const message = data.val();
callback({
id: data.key,
text: message.text,
createdAt: message.createdAt,
user: {
_id: message.user._id,
name: message.user.Uemail,
avatar: 'https://placeimg.com/140/140/any',
}
});
};
this.messagesRef.limitToLast(20).on("child_added", onReceive);
}
renderUsernameOnMessage={true}
Related
I'm trying to build a chat application in React Native where the listChats query is sorted by time but I have problems sorting with the new GraphQL transformer v2. How do I sort the model by time?
My chats model in the schema below...
type Chat #model {
id: ID!
content: String! #index(name: "chatsByDate", queryField: "chatsByDate", sortKeyFields: ["createdAt"])
createdAt: AWSDateTime!
file: String
userID: ID! #index(name: "byUser")
user: User #belongsTo(fields: ["userID"])
convoID: ID! #index(name: "byConvo")
convo: Convo #belongsTo(fields: ["convoID"])}
This is how I'm querying the data...
const fetchChats = async () => {
setLoading(true)
try {
const filter = {
convoID: {
eq: convoId
},
}
const chatsData = await API.graphql(graphqlOperation(listChats, {filter: filter}));
setChats(chatsData.data.listChats.items)
} catch (error) {
console.log(error)
} finally {
setLoading(false)
}
}
I added webRTC feature to make in app call using firebase and react native push notification. The problem is that the company wants the app to start and show the incoming call screen if the app is locked.
Is there any way to make this happen? And,Which resources I can use?
I am handling the background state using the setBackground handler provided from react-native-firebase, and the call is initialized by a push notification, which contains only data payload.
The handler is:
messaging().setBackgroundMessageHandler(async notification => {
let id = 1893950948;
console.log('#INITIAL ROUTE: ', notification);
if (notification.data.channelName === __config.BRAND_PSN_CHANNELS.RTC_CALL) {
if (notification.data.title === 'Incoming call') {
InCallManager.startRingtone('_BUNDLE_');
const {offer, name, sendingAgent} = notification.data;
PushNotification.localNotification({
id,
title: 'Incoming call',
message: `${name} is calling you`,
data: {...notification.data},
channelId: '2',
messageId: notification.messageId,
importance: 'max',
smallIcon: 'app_icon',
largeIcon: 'app_icon',
ongoing: true,
tag: 'call-user',
visibility: 'public',
actions: ['Answer', 'Decline'],
invokeApp: false,
priority: 'high',
});
// send the ringing event
axios.post(
`${API_BASE_URL}/${WEBRTC_URLS.ringingURI}/?token=${WEBRTC_URLS.webhookToken}`,
{
to: sendingAgent,
},
);
// set the data to the local storage
const storedCall = {
offer,
name,
sendingAgent,
};
// PushNotification.getDeliveredNotifications(notifications =>
// console.log(notifications),
// );
// set the data to the local storage
await AsyncStorage.setItem('storedCall', JSON.stringify(storedCall));
}
}
if (notification.data.title === 'Missed Call') {
PushNotification.removeAllDeliveredNotifications();
InCallManager.stopRingtone('_BUNDLE_');
await AsyncStorage.removeItem('storedCall');
await AsyncStorage.removeItem('notification');
}
return Promise.resolve();
});
i am able to generate notification along with action buttons but how to call a onpress event based on the button pressed by user? here yes or no
thanks in advance
import PushNotification from 'react-native-push-notification';
function configure() {
PushNotification.configure({
// (required) Called when a remote is received or opened, or local notification is opened
onNotification: function (notification) {
console.log('NOTIFICATION:', notification);
// process the notification
// (required) Called when a remote is received or opened, or local notification is opened
notification.finish();
},
// IOS ONLY (optional): default: all - Permissions to register.
permissions: {
alert: true,
badge: true,
sound: true,
},
// Should the initial notification be popped automatically
// default: true
popInitialNotification: true,
/**
* (optional) default: true
* - Specified if permissions (ios) and token (android and ios) will requested or not,
* - if not, you must call PushNotificationsHandler.requestPermissions() later
* - if you are not using remote notification or do not have Firebase installed, use this:
* requestPermissions: Platform.OS === 'ios'
*/
requestPermissions: true,
requestPermissions: Platform.OS === 'ios',
'content-available': 1,
});
}
function givenotification(title, message) {
PushNotification.localNotification({
channelId: 'channel',
message: message, // (required)
title: title,
message: message, // (required)
actions: ["Yes", "No"]
});
}
I have never used push notification directly,
for my notification i have use React Native Notifee that have this "displayNotification" inside when you try to log Notifee ..
I suggest you to try log "PushNotification" to find a function to display your notification.
You can setup the action as below code:
export const App = () => {
const [permissions, setPermissions] = useState({});
/**
* By calling this function, a notification with category `userAction` will have action buttons
*/
const setNotificationCategories = () => {
PushNotificationIOS.setNotificationCategories([
{
id: 'userAction',
actions: [
{id: 'open', title: 'Open', options: {foreground: true}},
{
id: 'ignore',
title: 'Desruptive',
options: {foreground: true, destructive: true},
},
{
id: 'text',
title: 'Text Input',
options: {foreground: true},
textInput: {buttonTitle: 'Send'},
},
],
},
]);
};
useEffect(() => {
PushNotificationIOS.addEventListener('notification', onRemoteNotification);
});
const onRemoteNotification = (notification) => {
const actionIdentifier = notification.getActionIdentifier();
if (actionIdentifier === 'open') {
// Perform action based on open action
}
if (actionIdentifier === 'text') {
// Text that of user input.
const userText = notification.getUserText();
// Perform action based on textinput action
}
};
};
For more, you can reach out to the official documentation of the library.
https://github.com/zo0r/react-native-push-notification
I am trying to build a chat feature for my application using React Native + Gifted Chat + expo + firebase realtime DB. I could build the module upto this part. I am using Firebase authentication and was wondering how can I associate these chats with the credentials of the user sending and receiving them - so that when they log back in - they can see their past chats and can know who sent them. It is only a one way chat as of now and I have just hardcoded one message and a user email id - but I want it to like :
user 1 logs in - sends 'Hi' to user 2
user 2 logs in and sees all past messages with User 1 and the new 'Hi' part.
I have added the previousState part of the code to append old messages - but it's not happening as I havent associated the current user with the chats till now.
Any idea on how to do it ? Help will be EXTREMELY appreciated !
I am authenticating using the Firebase Authentication :
Login = (email, password) => {
try {
firebase
.auth()
.signInWithEmailAndPassword(email, password)
.then(res => {
console.log(res.user.email);
this.props.navigation.navigate('MainMenu');
})
} catch (error) {
console.log(error.toString(error));
}
};
Code of my current Chat is as follows :
let saveMessage = message => {
db.ref('/messages').push({
messageText: message
});
};
class ChatPage extends React.Component {
state = {[![right now its just one-way chat - and no saving od ][1]][1]
messages: []
};
componentDidMount() {
this.setState({
messages: [
{
_id: 1,
text: "Hi there, how are you doing ?",
createdAt: new Date(),
user: {
_id: 2,
name: "user1#gmail.com",
avatar: "https://placeimg.com/640/480/nature"
}
}
]
});
}
onSend(messages = []) {
this.setState(previousState => ({
messages: GiftedChat.append(previousState.messages, messages),
}))
db.ref('/messages').push({ messages });
}
render() {
return (<KeyboardAvoidingView
style={{ flex: 1 }}
behavior="padding"
keyboardVerticalOffset={Platform.select({
ios: () => 0,
android: () => 100
})()}
><GiftedChat
messages={this.state.messages}
onSend={messages => this.onSend(messages)}
// user={{
// _id: 1,
// }}
user={this.state.email}
renderUsernameOnMessage={true}
/></KeyboardAvoidingView>)
}
}
So I'm building the chat functionality part for my app. I'm using sendbird sdk along with gifted chat for the UI.
My messages won't show up and I keep on getting the following warning.
'GiftedChat: _id is missing for message''
Now I've triple checked my sendbird is configured correctly, I'm logged in correctly and have also created the appropriate channel. These are both working.
Looking at the log of my messages they are posting as shown.
{
messageType: 'user',
messageId: 2122453749,
etc ...
}
But they are posting as messageId , Do I have to change the structure of this? If so how do I go about this as sendbird pre configures it already. Or can I change this in gifted-chat ?
Please take a look at the snippets of my code below.
getChannelMetaData(channel) {
if (channel) {
const self = this;
const messagesQuery = channel.createPreviousMessageListQuery();
messagesQuery.load(50, true, (messages, error) => {
if (error) {
console.error(error);
}
this.setState({
messages,
});
});
}
}
onSend(messages = []) {
const handle = this;
const sb = SendBird.getInstance();
const { channel } = this.props.navigation.state.params;
this.setState(previousState => {
channel.sendUserMessage(messages[0].text, (response, error) => {
if (!error) {
handle.getChannelMetaData(channel);
}
});
console.log(this.state.messages);
return { messages: GiftedChat.append(previousState.messages, messages) };
});
}
<GiftedChat
messages={this.state.messages}
renderBubble={bubble}
loadEarlier
renderLoadEarlier={loadEarlier}
isAnimated
keyboardShouldPersistTaps="never"
onSend={messages => this.onSend(messages)}
user={{
_id: userID,
}}
showUserAvatar
/>
You should use this format:
{
_id: 1,
text: 'message',
createdAt: new Date(),
user: {
_id: 2,
name: 'nickname',
avatar: 'YourimageURL',
},
},
If you don't follow the format specified by them, it throws this warning. So what we did for that ...we just customized our JSON object from the array of chat messages like below
let giftedChatMessages = chatMessages.map((chatMessage) => {
let gcm = {
_id: chatMessage.id,
text: chatMessage.get("text"),
createdAt: chatMessage.get("createdAt"),
user: {
_id: chatMessage.get("user").id,
name: chatMessage.get("user").get("name"),
avatar: chatMessage.get("user").get("avatarUrl")
}
};
return gcm;
});
messages={this.state.messages}
Here, {this.state.messages} should have the following structure
id:
text:
createdAt:
user: {
_id:
name:
avatar:
}
Option 1: You get all the corresponding field values as is from sendbird and update an intermediary array with the expected property names and then update this.state.messages
Option 2: Onsend function should insert the values for the following column headers in sendbird
id:
text:
createdAt:
user: {
_id:
name:
avatar:
}
So that, when you retrieve the message from sendbird, you get exactly the same fields as is expceted by giftedchat format.