I have onConnect Wallet Connection handler that triggers from electron app to establish socket connection and open external link on browser
const onConnetWallet = url => {
const newSocket = io(`http://192.168.3.51:3000`, {
auth: {
email: user?.email,
type: 'app'
}
})
newSocket.on('connect', () => {
alert(newSocket.id)
})
newSocket.on('response', update => {
alert(update)
})
window.ipcRenderer.sendSync('connectwallet')
}
Browser have the following function:
const handleWalletConnet = async () => {
const provider = new ethers.providers.Web3Provider(window.ethereum)
const res = await provider.send('eth_requestAccounts', [])
dispatch(
updateWallet({
walletAddress: res[0],
otpToken
})
)
// const walletConnected = await
newSocket.on('connect', () => {
console.log(newSocket.id)
})
newSocket.on('response', update => {
console.log(update)
})
setSocket(newSocket)
}
this function calls the metamask to connect wallet and calls the API to store the wallet address.
Now i need the socket to send the wallet connected message to App via app socket id.
To anonymously update the wallet connected when app connects wallet.
Related
We are creating a multiplayer quiz app that uses socket.io and React. We have got a create room and join room working, but when the host in the lobby starts the game only they progress to the question page, and no one else in the lobby goes anywhere.
This is our code in app.js
import io from "socket.io-client";
const URL = "http://localhost:3001"
const {
difficulty,
category,
socket,
setSocket,
setAllPlayers,
setUserData
} = useContext(QuizContext)
useEffect(() => {
const newSocket = io(URL)
newSocket.on("update_room", (users) => {
setAllPlayers(users);
setUserData(prev => {
return {...prev, room: users[0]?.room}
});
});
}, [])
useEffect(() => {
if(socket) {
socket.on("game_started", () => {
console.log(2);
navigate("/quiz")
});
}
}, [socket]);
This is the code in WaitingRoom.js
<button onClick={startQuiz}>Start</button
const startQuiz = () => {
socket.emit("start_quiz", { room: userData.room, data: userData.data });
};
This is the code in our backend on socketEvents/index.js
socket.on("start_quiz", ({ room, data }) => {
users = users.map((user) => {
return { ...user, data };
});
io.to(room).emit("game_started", users);
});
We've looked at all the socket.io documentation and can't figure out why it's not working.
I have a bucket into which users can upload audio files, and my goal is to test that it is working as expected. But when I try to use the "#firebase/rules-unit-testing" library to upload a test file into the emulator the upload gets stuck and makes no progress.
Rules
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if false;
}
match /audio/{audioFileID} {
allow create: if request.auth != null && request.resource.contentType.matches('audio/(flac|wav)');
}
}
}
Test code
import {
assertFails,
assertSucceeds,
initializeTestEnvironment,
RulesTestEnvironment,
} from "#firebase/rules-unit-testing";
import { test, beforeAll, beforeEach, afterAll } from "vitest";
import fs from "fs";
const createTestFile = (size: number) => Buffer.alloc(size);
let testEnv: RulesTestEnvironment;
beforeAll(async () => {
testEnv = await initializeTestEnvironment({
projectId: "stst-et-interviewer-dev",
hub: {
host: "localhost",
port: 4400,
},
});
});
beforeEach(async () => {
await testEnv.clearStorage();
await testEnv.clearFirestore();
});
afterAll(async () => await testEnv.cleanup());
const loadStepStoneImage = () =>
fs.readFileSync("./public/images/stepstoneLogo.svg");
test("Storage does not allow you to read files", async () => {
const rouge = testEnv.unauthenticatedContext();
const alice = testEnv.authenticatedContext("alice");
await assertFails(
rouge.storage().ref("audio/test-interview.flac").getDownloadURL()
);
await assertFails(
alice.storage().ref("audio/test-interview.flac").getDownloadURL()
);
await assertFails(alice.storage().ref("audio/").listAll());
});
test("Storage does not allow you to upload a file if you are not logged in", async () => {
const rouge = testEnv.unauthenticatedContext();
const upload = rouge
.storage("stst-et-interviewer-dev.appspot.com")
.ref("audio/logo.svg")
.put(createTestFile(200), { contentType: "audio/flac" });
await assertFails(upload.then()); // <- GETS STUCK HERE
console.log("this does not happen");
});
What are the possible reasons for this happening? Are there any simple ways of debugging?
I have an embedded app in shopify which is an paid app ,Once user approves the billing ,i want the app to show the confirmation url in the embedded app itself instead it loads externally.
getsubscriptionurl.js
export const getSubscriptionUrl = async (ctx, shop) => {
const { client } = ctx;
console.log(`process.env.HOST - ${process.env.HOST}`);
console.log(`shop - ${shop}`);
console.log(`${process.env.HOST}/?shop=${shop}`);
const confirmationUrl = await client
.mutate({
mutation: RECURRING_CREATE(),
variables: {
returnUrl: `www.abc.com`,
}
})
.then(response => response.data.appSubscriptionCreate.confirmationUrl);
console.log("me "+ confirmationUrl);
return ctx.redirect(confirmationUrl);
};
server.js
app.prepare().then(async () => {
const server = new Koa();
const router = new Router();
server.keys = [Shopify.Context.API_SECRET_KEY];
server.use(
createShopifyAuth({
async afterAuth(ctx) {
// Access token and shop available in ctx.state.shopify
const { shop, accessToken, scope } = ctx.state.shopify;
const host = ctx.query.host;
ACTIVE_SHOPIFY_SHOPS[shop] = {scope:scope,accessToken:accessToken};
const response = await Shopify.Webhooks.Registry.register({
shop,
accessToken,
path: "/webhooks",
topic: "APP_UNINSTALLED",
webhookHandler: async (topic, shop, body) =>
delete ACTIVE_SHOPIFY_SHOPS[shop],
});
if (!response.success) {
console.log(
`Failed to register APP_UNINSTALLED webhook: ${response.result}`
);
}
// Redirect to app with shop parameter upon auth
// ctx.redirect(`/?shop=${shop}&host=${host}`);
server.context.client = await handlers.createClient(shop, accessToken);
await handlers.getSubscriptionUrl(ctx, shop);
},
})
);
You can't basically show the confirmation URL in your app, Shopify won't trust app developers to take sensitive info like payment details, so must open the confirmation URL into a new tab, where the merchant is viewing a Shopify payment page(made by shopify) that contains the payment details to be entered and on confirm the page will redirect the merchant to the return URL as you specified before.
For testing purposes
you can send a test param within the query to allow you to test without entering any payment details
const CREATE_SUB_MUTATION_RECURRING_ONLY = gql`
mutation RecurringSubscription(
$returnUrl: URL!
$test: Boolean!
$planName: String!
$amount: Decimal!
) {
appSubscriptionCreate(
test: $test
name: $planName
returnUrl: $returnUrl
lineItems: [
{
plan: {
appRecurringPricingDetails: {
price: { amount: $amount, currencyCode: USD }
interval: EVERY_30_DAYS
}
}
}
]
) {
userErrors {
field
message
}
confirmationUrl
appSubscription {
id,
currentPeriodEnd
}
}
}
`;
Now to test just pass true to test
result = await graphQlClient?.mutate({
mutation: CREATE_SUB_MUTATION_RECURRING_ONLY,
variables: {
returnUrl,
test,
planName: PLANS_DATA[planName].planName,
amount: PLANS_DATA[planName].price,
},
});
i am trying to implement a 1-1 private messaging feature inside my app, where 2 users can exchange messages live if they are both on the chat screen at the same time and if not the messages get stored in my postgres database and when the user opens the chat again they are loaded.
Currently with my code, when both users chat are open, when i try sending a message, the message does not get sent live i need to refresh the app in order for the chat to update. I think my socket is working since my console logs are getting returned in both frontend and backend consoles.
my problem is how to make the messages live and update my flatlist correctly(ie. the new messages appear at the bottom of my inverted list)?
Here is my code:
Client Side
const message = route.params.message;
const [messages, setMessages] = useState([]);
const [text, setText] = useState('');
const [socket, setSocket] = useState(null);
const { user } = useAuth();
useEffect(() => {
const newsocket =io.connect(socketURL)
setMessages(message.Messages)
newsocket.on('connect', msg => {
console.log(`user: ${user.id} has joined conversation ${message.id}`)
setSocket(newsocket)
});
newsocket.on("send_message", (msg) => {
console.log("this is the chat message:", msg);
const data = [...messages];
data.push(msg);
setMessages(data);
});
return(()=>newsocket.close());
}, []);
const onSend = (ConversationId,senderId,receiverId,message) => {
messagesApi.sendMessage({ConversationId,senderId,receiverId,message});
setText("")
const to = (user.id===route.params.message.user1?
route.params.message.user2:route.params.message.user1)
socket.emit(
'message', { to: to, from: user.id, message,ConversationId });
};
const updateText=(text)=>{
setText(text);
}
<FlatList
inverted
data={messages}
keyExtractor={(item,index)=>index.toString()}
extraData={messages}
renderItem={({item,index})=>(
<>
<Text>
{moment(item.createdAt).fromNow()}
</Text>
<MessageBubble
text={item.message}
mine={item.senderId !== user.id}
/>
</>
)}
bounces={false}
/>
<View style={styles.messageBoxContainer}>
<TextInput
onChangeText={updateText}
value={text}
/>
<TouchableOpacity
onPress={()=>{
onSend(
message.id,
user.id,
(user.id===message.user1?message.user2:message.user1),
text
)}}
>
<Text>Send</Text>
</TouchableOpacity>
</View>
Server Side
const express = require("express");
const app = express();
const http = require("http");
const socket = require("socket.io")
const server=http.createServer(app);
const io =socket(server)
io.on('connection', (socket) => {
console.log("connected")
socket.on('message', (data) => {
console.log(data)
socket.emit('send_message', { message: data.message, receiverId:
data.to,senderId:data.from,conversationId:data.ConversationId })
});
});
Thank you in advance, i have been trying to solve this problem for weeks and couldnt. Would really appreciate any help.
after many attempts i managed to get it working thanks to Srikanth's answer on this Creating a private chat between a key using a node.js and socket.io.
CLIENT
useEffect(() => {
const newsocket =io.connect("http://192.168.1.103:9000")
setMessages(message.Messages)
newsocket.on('connect', msg => {
console.log(`user: ${user.id} has joined conversation ${message.id}`)
setSocket(newsocket)
newsocket.emit('subscribe', message.id);
});
newsocket.on("send_message", (msg) => {
console.log("this is the chat messages:", msg);
setMessages(messages => messages.concat(msg))
});
return(()=>newsocket.close());
}, []);
const onSend = (ConversationId,senderId,receiverId,message) => {
console.log("sent")
const to = (user.id===route.params.message.user1?
route.params.message.user2:route.params.message.user1)
socket.emit('message', { to: to, from: user.id, message,ConversationId });
setText("")
messagesApi.sendMessage({ConversationId,senderId,receiverId,message});
};
SERVER
io.on('connection',(socket)=>{
console.log('User '+socket.id+' connected')
socket.on('subscribe', (room)=> {
console.log('joining room', room);
socket.join(room);
});
socket.on('message', (data) => {
console.log(data)
console.log('sending room post',data.ConversationId)
io.sockets.in(data.ConversationId).emit('send_message', { message:
data.message, receiverId:
data.to,senderId:data.from,conversationId:data.ConversationId });
})
})
I have read many comments that suggested not to use rooms in 1-1 private messaging but this was the only possible way of getting it to work.
I have the following setup which works on my PC but doesn't on mobile even when there is data to fetch.
useEffect(() => {
const {username, room} = queryString.parse(location.search);
setRoom(room);
if (messages.length > 3) {
let lastMessage = messages.pop();
setMessss([lastMessage]);
const fetchHistory = async () => {
try {
const result = await axios.get(`https://example.com/messages/${room}`,);
setMessss(result.data.messagesFromAPI);
} catch (error) {
console.log(error);
}
};
fetchHistory();
}
}, [messages]);
I also have another useEffect hook that works on PC on componentDidMount but doesn't work if I reload the page more than once but I want it to work on every page reload but it doesn't fetch...
could this be because I use the free subscription (M0) on Mongodb Atlas? Although from metrics my database hasn't exhausted or reached capacity.
useEffect(() => {
const {username, room} = queryString.parse(location.search);
// setRoom(room);
axios.get(`https://example.com/messages/${room}`)
.then(response => {
const history = response.data.messagesFromAPI;
setMessss(history);
})
.catch(error => {
console.log(error.response);
});
},[]);
Here's how I solved it
In the src folder just add a file called
setupProxy.js
and write this code inside
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
["/api/*",], // the base api route you can change it
createProxyMiddleware({
target: "http://localhost:4000", // the local server endpoint
})
);
};
make sure to change the target port to the port where the server is running.
For some reason axios does not behave properly locally.
You can add the setupProxy.js to .gitignore