0

I am trying to achieve one-to-one messaging in react native using the firebase real time database. I am very new to react native/firebase and I am not too sure how I can send a message to a specific user uid. I have seen a few links online which uses firebase firestore for group chats but I would like to perform this using the real time database and only one-to-one messaging. So far I have managed to send a message in my app but I am displaying all messages from all users from the database too when logged in as the current user. I am using react-native-gifted-chat for the UI.

// This is file MessagesScreen.js

class MessagesScreen extends Component {
  state = {
    messages: []
  }  

  get user() {
    return {
      _id: FireMessage.uid,
    }
  }

  componentDidMount() {
    FireMessage.get(message => this.setState(previous => ({
      messages: GiftedChat.append(previous.messages, message)
    })));
  }

  componentWillUnmount() {
    FireMessage.off();
  }

  render() {
    const chat = <GiftedChat messages={this.state.messages} onSend={FireMessage.send} user={this.user} />;

    if (Platform.OS === "android") {
      return (
        <KeyboardAvoidingView style={{ flex: 1}} behavior="padding" keyboardVerticalOffset={10} enabled>
          {chat}
        </KeyboardAvoidingView>
      );
    }

    return <SafeAreaView style={{ flex: 1}}>{chat}</SafeAreaView>;
  }
}

export default MessagesScreen;
// This is file FireMessage.js

class FireMessage {

  constructor() {
    this.init()
    this.checkAuth() 
  }

  init = () => {
    if (!firebase.apps.length && firebaseConfig.apps.length === 0) {
      firebase.initializeApp({
        apiKey: "xxxxxxxxxxx",
        authDomain: "xxxxxxxxxxx",
        databaseURL: "xxxxxxxxxx",
        projectId: "xxxxxxxx",
        storageBucket: "xxxxxxxxxx",
        messagingSenderId: "xxxxxxxx",
        appId: "xxxxxxxxxxx",
        measurementId: "xxxxxxxxx"
      });
    }
  };

  checkAuth = () => {
    firebase.auth().onAuthStateChanged(user => {
      if (!user) {
        firebase.auth().signInAnonymously();
      }
    });
  };

  send = messages => {
    messages.forEach(item => {
      const message = {
        text: item.text,
        timestamp: firebase.database.ServerValue.TIMESTAMP,
        user: item.user
      };

      this.db.push(message)
    });
  };

  parse = message => {
    const { user, text, timestamp } = message.val();
    const { key: _id } = message;
    const createdAt = new Date(timestamp);


    return {
      _id,
      createdAt,
      text,
      user
    };
  };
 
  get = callback => {
    this.db.on("child_added", snapshot => 
      callback(this.parse(snapshot)));
  };

  off() {
    this.db.off();
  }

  get db() {
    return firebase.database().ref("messages");
  }

  get uid() {
    return (firebase.auth().currentUser || {}).uid;
  }
}

export default new FireMessage();

Realtime Database structure:

Database structure of messages

Database structure of users

samthecodingman
  • 23,122
  • 4
  • 30
  • 54
AJDee
  • 147
  • 1
  • 14
  • 1
    Welcome to StackOverflow! To help us aid you better please clean the indentation of your code and place files in their own code blocks. e.g. if the class `FireMessage` is in it's own file, separate it from your component. It often helps those who answer your question if you add the filename on the first line like: `// This is ./fire-message.js`. – samthecodingman Jun 02 '21 at 06:01
  • Thanks for your quick response. I have tried to ident as much as I can. I have also separated the components. Can you help at all? – AJDee Jun 02 '21 at 07:09
  • Thanks for the edit. Do you know how I can solve this? – AJDee Jun 02 '21 at 07:53
  • I'm not familiar enough with react before hooks were introduced and don't have the time available to be able to learn it. There are a number of steps you need to do: Sign in users properly (anon user IDs change each login), update UI & Database to support "chat rooms" (see [this answer](https://stackoverflow.com/a/66838632/3068190) for creating room IDs and [this answer](https://stackoverflow.com/a/67348512/3068190) for securing them) and implement a secure, claimable map between usernames and userIDs (see [this answer](https://stackoverflow.com/a/67305111/3068190)). – samthecodingman Jun 03 '21 at 11:00
  • Thank you. How would get the uid of the receiver who isn't the current logged in user? And where would I place this if you don't mind me asking? – AJDee Jun 04 '21 at 07:50
  • You'd have to add some search feature to find the user you want to message (like a username). Regarding where you place it, your code needs a complete restructure to support 1-to-1 messaging, it's not as simple as drag and drop. The answers I linked are just the pieces, it's up to you to determine how to fit them together. If you can't figure out how to put it together, hire a developer to spend some time on it. – samthecodingman Jun 04 '21 at 13:10
  • Hi, I've already implemented code for 1-1 chat using firebase. If you need code then I share it with you. Just as @samthecodingman said it depends on how you want to implement the chat feature. What that chat includes ( only text message or with file share ) because to add an extra feature that can affect the current documentation structure implemented for a chat. – Vinit Bhavsar Nov 21 '21 at 06:32
  • Chat basically runs on a thread system. When One user sends the first message it creates a separate node for that 2 users. where all messages are inserted under that node. If you want it like WhatsApp like one user delete the entire chat but for the 2nd user it is still there then it becomes more complex to manage. – Vinit Bhavsar Nov 21 '21 at 07:06

0 Answers0