Wix release the new wix-realtime which allow developers to build interactive apps like chat app, multi-player game etc.
So, In this example i will discuss how we can build a chat app where a user can send a message to person B and person B immediatly get the message.
If you want to test it live here is the link:
https://test.salman2301.com
Overview
Front-end we use custom element, which allows to show the message side by side and also with custome element, we can have a fix height and scroll bar so user can scroll to previous messages. We can use repeater for this but we need to use pagination or infinite scrolling which is why i didn't. On the Backend, we use wix-realtime API with datahook - datahook runs the code when a new row is inserted in the database.
- realtime API allow us to do pub/sub ( publish/ subscriber) where sender or publisher send message to a channel and the reciever or subscriber can reciver the message.
Dataflow
If a user Person A send a message to Person B, the message will be inserted in the database and this runs the afterInsert data hook and the data hook use realtime api to publish to a channel, the name of the channel is same as the Person B user id. In this way, only the person B recieve the message and On the front-end, let's assume that the person B is online and we subscribe to the channel and the name of the channel Is the current user id. We get the user id from wix-user module wixUser.currentUser.id.
Database
Database Name: message Fields:
field_key data
from - USER_ID
to - USER_ID
message - Message
Code
// backend/data.js
import {publish} from 'wix-realtime-backend';
// datahook runs when a new row is inserted in the database
// item contains inserted row information { from: "uuid", to:"uuid", message:"hello"}
export function message_afterInsert(item, context) {
const { from, to, message, _id } = item;
const channel = { name : to};
let data = {
        message,
from,Â
        _id
    };
 // publish which take a channel name and data.
publish(channel, data, {includePublisher: true});
return item;
}
// Page code
import * as realtime from "wix-realtime";
import wixUsers from "wix-users";
import wixData from "wix-data";
import { getUsers, getMe } from "backend/getUsers.jsw";
let lastUserId, lastLoginEmail, lastPicture;
let userId = wixUsers.currentUser.id;
let owner;
$w.onReady(function () {
//Â $w('#dataset1').onReady(init);
  init();
  $w("#inSearch").onKeyPress((e) => {
    setTimeout(() => {
if (e.key === "Enter") filterMem();
if (e.key === "Escape") {
       $w("#inSearch").value = "";
       filterMem();
      }
    }, 40);
  });
  $w("#ChatElement").setAttribute(
"append-msg",
    JSON.stringify({
      user: {
        name: "salman",
      },
      msg: " Hello this is a test",
      date: new Date().toISOString(),
      isOwner: true,
    })
  );
  getMe().then((data) => {
    owner = data;
  });
});
function init() {
// wix real time
const channel = { name: userId };
  realtime.subscribe(channel, newMessage);
// update UI
  filterMem();
//Â events
  $w("#repeaterUser").onItemReady(($item, itemData, i) => {
let { loginEmail, picture } = itemData;
    $item("#image1").src = picture;
    $item("#textEmail").text = loginEmail;
  });
  $w("#containerUser").onClick((e) => {
    switchUser(e.context.itemId);
  });
  $w("#btnSend").onClick(sendMessage);
  $w("#inMessage").onKeyPress((e) => {
const { ctrlKey, key } = e;
if (key === "Enter" && !ctrlKey) {
      sendMessage();
    }
  });
}
async function filterMem() {
let inMember = $w("#inSearch").value || undefined;
  getUsers(inMember)
    .then((data) => {
      $w("#repeaterUser").data = data.items;
if (!lastUserId) {
        switchUser(data.items[0]._id);
      }
    })
    .catch(console.error);
}
async function switchUser(toUserId) {
  lastUserId = toUserId;
  $w("#repeaterUser").onItemReady(($item, itemData, i) => {
let { _id, loginEmail, picture } = itemData;
if (_id === toUserId) {
      $item("#imgCurrUser").show();
      $w("#textHeadUser").text = `Connected to ${loginEmail}`;
      lastLoginEmail = loginEmail;
      lastPicture = picture;
      refreshMsg();
    } else {
      $item("#imgCurrUser").hide();
    }
  });
}
async function newMessage({ payload }) {
  appendMsg(payload._id);
}
async function refreshMsg() {
  $w("#ChatElement").setAttribute("messages", "[]");
let resMsgs = await wixData
    .query("message")
    .eq("from", userId)
    .eq("to", lastUserId)
    .or(wixData.query("message").eq("from", lastUserId).eq("to", userId))
    .ascending("_createdDate")
    .find();
let msg = resMsgs.items;
let username = lastLoginEmail.split("@")[0];
  msg = msg.map((el) => {
let isOwner = userId === el.from;
let userImage = isOwner ? owner.picture : lastPicture;
    userImage = encodeURI(userImage);
if (!userImage.startsWith("https://")) userImage = undefined;
return {
      _id: el._id,
      isOwner: isOwner,
      user: {
        name: username,
        image: userImage,
      },
      msg: el.message,
      date: el._createdDate,
      data: el,
    };
  });
  $w("#ChatElement").setAttribute("messages", JSON.stringify(msg));
if (msg.length === 0) {
    $w("#textNoMsg").show();
  } else {
    $w("#textNoMsg").hide();
  }
}
async function appendMsg(msgId) {
let resMsgs = await wixData.query("message").eq("_id", msgId).find();
let message = resMsgs.items[0];
  console.log({ resMsgs });
let username = lastLoginEmail.split("@")[0];
let isOwner = userId === message.from;
let userImage = isOwner ? owner.picture : lastPicture;
  userImage = encodeURI(userImage);
if (!userImage.startsWith("https://")) userImage = undefined;
let msg = {
    _id: message._id,
    isOwner: isOwner,
    user: {
      name: username,
      image: userImage,
    },
    msg: message.message,
    date: message._createdDate,
    data: message,
  };
if (!(lastUserId === message.from || lastUserId === message.to)) {
    console.error(" No for the current user show alert!");
return;
  }
  $w("#ChatElement").setAttribute("append-msg", JSON.stringify(msg));
}
async function sendMessage() {
try {
    $w("#btnSend").disable();
let msg = $w("#inMessage").value;
if (!msg) return;
let toInsert = {
      from: userId,
      to: lastUserId,
      message: msg,
    };
let inserted = await wixData.insert("message", toInsert);
    appendMsg(inserted._id);
    $w("#btnSend").enable();
    $w("#inMessage").value = "";
  } catch (e) {
    console.log("ERROR : ", e.message);
    $w("#btnSend").enable();
    $w("#inMessage").value = "";
  }
}
For the custome element check my github
https://github.com/Salman2301/wix-chat-component
Wow, your information is nice we will try this soon and thanks for posting this and keep it up.
_____________________________________
from:- cheap digitizing embroidery
how do i set up the front end elements? please help me
Excellent. Will try.