Gifted chat missing '_id' for message - React Native - react-native

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.

Related

composition api - watch what object was changed

Is possible to catch what object was mutated?
const users = reactive([
{ name: 'User1', phone: '12345'},
{ name: 'User2', phone: '67890'},
{ name: 'User3', phone: '34567'},
]);
watch(users, (val) => {
console.log(val);
}, {deep: true});
Now i getting a full array of users, but want to get something like:
users[0].name was changed
or
users[1].phone was changed
I have tried to use this syntax
watch(users.name, (val) => {
console.log(val);
}, {deep: true});
but got an errors...

Keystone.js 6 access denied adminMeta

i want to seed data onConnect, but i have access denied, using this query :
{
keystone: keystone {
adminMeta {
lists {
key
description
label
singular
plural
path
fields {
path
}
}
}
}
i have this error even iam using sudo, context.sudo().graphql.raw :
[
Error: Access denied
at /Users/sidalitemkit/work/web/yet/wirxe/wirxe-app/node_modules/#keystone-next/admin-ui/system/dist/admin-ui.cjs.dev.js:552:19
at processTicksAndRejections (node:internal/process/task_queues:94:5)
at async Promise.all (index 0)
at async Promise.all (index 0) {
locations: [ [Object] ],
path: [ 'keystone', 'adminMeta' ]
}
]
here my config :
export default auth.withAuth(
config({
db: {
adapter: 'prisma_postgresql',
url:
'postgres://admin:aj093bf7l6jdx5hm#wirxe-app-database-do-user-9126376-0.b.db.ondigitalocean.com:25061/wirxepool?schema=public&pgbouncer=true&sslmode=require',
onConnect: initialiseData,
},
ui: {
isAccessAllowed: (context) => !!context.session?.data,
},
lists,
session: withItemData(
statelessSessions({
maxAge: sessionMaxAge,
secret: sessionSecret,
}),
{ User: 'email' },
),
}),
);
i figured out that when i do :
isAccessAllowed: (context) => true
it's working
any advice here
context.sudo() disabled access control. there could be some issue with your query. isAccessAllowed: (context) => true is related to admin-ui and not to the backend implementation of graphql. This could be a bug please open a bug in the repo. They whould be able to fix it quickly.
I do not see sample initialiseData to try myself. Also the graphql is designed as such if you try to access some non existing item then it may give you access denied error even though there is not access control (all access set to true).
There is also another api which is easier in creating the initial items. You should use new list api, available as context.sudo().lists.<ListName>.createOne or createMany like this
const user = await context.sudo().lists.User.createOne({
data: {
name: 'Alice',
posts: { create: [{ title: 'My first post' }] },
},
query: 'id name posts { id title }',
});
or
const users = await context.lists.User.createOne({
data: [
{
data: {
name: 'Alice',
posts: [{ create: { title: 'Alices first post' } }],
},
},
{
data: {
name: 'Bob',
posts: [{ create: { title: 'Bobs first post' } }],
},
},
],
query: 'id name posts { id title }',
});
for more details see List Items API and Database Items API in their preview documentation.
You can find a working example in keystonejs repository (blog)
You have to await and pass context to the initialiseData() method. The onConnect hook already provides this context for you
also, you can look for an argument like '--seed-data' so it's only run once
and run the code as:
keystone --seed-data
export default auth.withAuth(
config({
db: {
adapter: 'prisma_postgresql',
url:
'postgres://admin:aj093bf7l6jdx5hm#wirxe-app-database-do-user-9126376-0.b.db.ondigitalocean.com:25061/wirxepool?schema=public&pgbouncer=true&sslmode=require',
async onConnect(context) {
if (process.argv.includes('--seed-data')) {
await initialiseData(context);
}
},
},
ui: {
isAccessAllowed: (context) => !!context.session?.data,
},
lists,
session: withItemData(
statelessSessions({
maxAge: sessionMaxAge,
secret: sessionSecret,
}),
{ User: 'email' },
),
}),
);

How can I implement a two-way chat feature using gifted chat and firebase authentication?

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>)
}
}

react native chat render the username

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}

Realm "observer.next create #[native code]" exception

I am trying to fetch data with apollo and then write it to realm. I have created a js file that I know works, because it has worked before. But, when I try to write to a particular model I get an error message. More details as follows:
Code (Not entire code) LocationQuery.js:
const realm = new Realm({ schema: [testBuilding1], schemaVersion: 1 });
let buildingTypeArray = [];
const temp = [];
class LocationQuery extends Component {
static get propTypes() {
return {
data: React.PropTypes.shape({
loading: React.PropTypes.bool,
error: React.PropTypes.object,
sites: React.PropTypes.array,
}).isRequired,
};
}
render() {
if (this.props.data.loading) {
return (null);
}
if (this.props.data.error) {
return (<Text>An unexpected error occurred</Text>);
}
if (this.props.data.sites) {
this.props.data.sites.map((value) => {
buildingTypeArray.push(value.locations);
});
buildingTypeArray.forEach((locationValues) => {
realm.write(() => {
realm.create('testBuilding1', {
building: '273',
});
});
});
}
return null;
}
}
const locationQueryCall = gql`
query locationQueryCall($id: String!){
sites(id: $id){
locations {
building
type
}
}
}`;
const ViewWithData = graphql(locationQueryCall, {
options: props => ({
variables: {
id: 'SCH1',
},
}),
})(LocationQuery);
export default connect(mapStateToProp)(ViewWithData);
The error I get is a big red screen that read:
console.error: "Error in observe.next.... blah blah blah"
The Model I am using:
export const testBuilding1 = {
name: 'testBuilding1',
properties: {
building: 'string',
},
};
The weird thing is that the code works when I use this model:
export const locationScene = {
name: 'locationScene',
properties: {
building: 'string',
},
};
I am calling LocationQuery.js in another piece of code passing it through at render.
Thank you in advance for the help!