I get error when trying to subscribe to the getStream Websocket - getstream-io

Currently, I am integrating websockets for the feeds using GetStream JS library.
But I can't subscribe to the websocket by following the instruction
I have created Flat Feeds and it's working fine. I can do all the actions with activities. But I need to integrate my app with websocket so that it can update the feed live.
I've followed the steps that described in the feed document
async initializeStream(profile, followings = []) {
try {
const { peerID } = profile;
const response = await getStreamToken(peerID);
const { token } = response;
this.token = token;
this.client = stream.connect(STREAM_API_KEY, token, STREAM_APP_ID);
await this.createUser(profile);
this.feed = this.client.feed('user', peerID, token);
this.globalFeed = this.client.feed('user', 'all', token);
return true;
} catch (err) {
return false;
}
}
This is stream initialization part and it works fine without any flaw.
And below is subscription function:
subscribe (subscribingFunction) {
return this.feed.subscribe(subscribingFunction);
}
And this one is how I am using subscription function to integrate websocket:
StreamClient.subscribe((data) => {
console.log('stream - update received');
console.log(data);
// return emitter({ type: 'STREM/UPDATE_RECEIVED', payload: data });
}).then(response => {
console.log('success', response)
}).catch(response => {
console.log('failure', response)
});
Expected Result:
Websocket subscription is success and I can get the live updates through it.
Result:
I am getting this error when trying to subscribe to websocket:
klass {code: null, params: Array(0), message: "Failed to authenticate. Please check your API Token, App ID and Feed ID."}
Can you point me out what went wrong with this configuration?
Here's code for the getStreamToken function:
export const getStreamToken = (userId) => {
const apiURL = `${tokenServerAPI}/getToken?user_id=${userId}`;
const headers = {
method: 'GET',
headers: {
authorization: `Basic ${base64.encode('ob_stream_user:ob_stream_pwd')}`,
},
};
return fetch(
apiURL,
headers,
).then(response => response.json()).catch(err => {
console.log(err);
});
};

Related

In React 18, when I am sending data to nodejs server, it is sending two request and receiving two response from server

This is the front-end code which is used for sending access token to server site.
useEffect(() => {
const getProducts = async () => {
try {
const url = `http://localhost:5000/product?email=${user.email}`
const { data } = await axios.get(url, {
headers: {
authorization: localStorage.getItem('accessToken')
}
});
setProducts(data);
} catch (err) {
const status = err.response.status;
if (status === 401 || status === 403) {
signOut(auth);
navigate('/login');
localStorage.removeItem('accessToken')
toast.error(err.response?.data?.message);
}
}
}
getProducts();
}, [user.email]);
This is server site express code for response. Why every time it is receiving two request and sending two response?
app.get('/product', verifyToken, async (req, res) => {
const decoded = req.decoded?.email;
const queryEmail = req.query?.email;
if (decoded === queryEmail) {
const query = { email: queryEmail };
const cursor = medicineCollection.find(query);
const products = await cursor.toArray();
res.send(products);
} else {
res.status(403).send({ message: "Forbidden Access" })
}
})
Maybe you take user.email in a state which is updating somehow so that's why useEffect is calling again and giving you twice response.

how to call async inside another async

I am trying to get some data using an API with an accessToken which is encrypted in the database, I am fetching it then decrypting so I can use it to make the API call as follows:
async function getUserGuilds(discord_id) {
//Get Token
const tokenQuery = 'SELECT e_accesstoken FROM users WHERE discord_id = $1';
const discordID = [discord_id];
db.query(tokenQuery, discordID, (err, res) => {
if (err) {
console.log(err);
} else if (!err) {
const encryptedAccessToken = res.rows[0].e_accesstoken
const decrypted = decrypt(encryptedAccessToken);
const accessToken = decrypted.toString(CryptoJS.enc.Utf8);
}
})
//Call the API after getting the token
const response = await fetch(`${DISCORD_API}/users/#me/guilds`, {
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`
}
});
return response.json();
}
as you can see the accessToken is outside the scope, how can I access it and use it for the API call? What is the best practice?
// Since you are using async keywork, this function automatically returns
// a Promise, therefore you will need to handle it with a .then() or await
// in order to get the result.
async function getUserGuilds(discord_id) {
return new Promise((resolve, reject) => {
//Get Token
const tokenQuery = 'SELECT e_accesstoken FROM users WHERE discord_id = $1';
const discordID = [discord_id];
db.query(tokenQuery, discordID, async (err, res) => {
if (err) {
console.log(err);
// Rejecting the promise error here will stop the execution, therefore you will not need to
// add an else statement
return reject(error);
}
const encryptedAccessToken = res.rows[0].e_accesstoken
const decrypted = decrypt(encryptedAccessToken);
const accessToken = decrypted.toString(CryptoJS.enc.Utf8);
// Always wrap async operations with try/catch because they will fail
// at some point, therefore your code must be prepared to handle it
try {
//Call the API after getting the token
const response = await fetch(`${DISCORD_API}/users/#me/guilds`, {
method: 'GET',
headers: { Authorization: `Bearer ${accessToken}` }
});
resolve(response.json());
} catch (error) {
reject(error);
}
});
});
}
The tip is, as soon you start to dealing with asynchronous code, try to write you own functions in an asynchronous manner.

Fetch api not posting data to backend server

I am using cognitive service by azure which I am using Face API, In frontend the user will take picture then will call the API to check if face detected or not after that face id will be added using Add Face under FaceList as in azure documentation, after that I want to update column in database if face added successfully, here i am calling a function called senddata() which will use fetch API to send data to backend server then in server the database column will be updated, the problem is after face added successfully the senddata() function is not posting any data to backend server:
here is the code of taking picture:
const takePicture = async () => {
if (camera) {
const data = await camera.current.takePictureAsync({ quality: 0.25, base64: true });
const selfie_ab = base64ToArrayBuffer.decode(data.base64);
setTakingPic(true)
try {
const facedetect_instance_options = { ...base_instance_options };
facedetect_instance_options.headers['Content-Type'] = 'application/octet-stream';
const facedetect_instance = axios.create(facedetect_instance_options);
const facedetect_res = await facedetect_instance.post(
`/detect?returnFaceId=true&detectionModel=detection_02`,
selfie_ab
);
console.log("face detect res: ", facedetect_res.data);
if (facedetect_res.data.length) {
const add_face_instance_options = { ...base_instance_options };
add_face_instance_options.headers['Content-Type'] = 'application/octet-stream';
const add_face_instance = axios.create(add_face_instance_options);
const addface_res = await add_face_instance.post(
`/facelists/${facelist_id}/persistedFaces`, selfie_ab
);
if (addface_res.data.persistedFaceId.length) {
const status = "on hold";
const faceid = addface_res.data.persistedFaceId;
senddata(status, faceid)
console.log("Face add and send for approval: ", addface_res.data.persistedFaceId);
} else {
Alert.alert("error", "something went wrong");
}
} else {
Alert.alert("error", "Detection failure. Please make sure there is sufficient light when taking a selfie");
}
} catch (err) {
console.log("err: ", err);
}
}
};
here the senddata() function:
const senddata = (status, faceid) => {
console.log(status)
console.log(faceid)
fetch('http://*********/users/updateRegStatus', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
status: status,
faceid: faceid
})
})
.then((response) => response.json())
.then((res) => {
if (res.success === true) {
alert(res.message);
navigation.navigate('dashboard')
}
else {
alert(res.message);
}
})
}
and the following code form the backend which for updating the database:
router.post('/updateRegStatus', function (req, res, next) {
var status = req.body.status;
var faceid = req.body.faceid;
connection.query("INSERT INTO face_status (status,faceid) VALUES (?,?) ", [status, faceid], function (err, row) {
if (err) {
console.log(err);
} else {
res.send({ 'success': true, 'message': 'Your face details sent for approval' });
}
});
});
pleaser help me

What is the proper way to execute axios / firebase promises in a specific order in a firebase function?

What is the best way to chain axios / firebase promises that must be linked in a specific order and use the returns of previous promises?
I am writing a firebase function that allows me to update a user via a third-party JWT API. So I have to fulfill several promises (I use axios for that) to build the final query with a uid, a token and a refresh token.
These requests must be executed in the right order, each promise waiting for the result of the previous one to be able to execute.
recover the firebase client token to identify the user
search in a collection for the tokens (access & refresh) that were previously stored and associated with the user's uid.
Execute the "me" request on the third-party API to retrieve the user's information and update the user.
My question: What is the most correct way to chase these axios promises?
For the moment, I have managed to achieve this result, by interlocking the calls successively to properly manage the "catch" and by moving in separate functions the calls to make a little more digest the reading of the code.
/* index.js */
const userModule = require('./user');
exports.me = functions.https.onRequest( (request, response) => {
cors(request, response, () => {
let idToken = request.body.data.token;
userModule
.get(idToken)
.then((uid) => {
console.log('User found : ' + uid);
return userModule
.retrieve(uid)
.then((userTokens) => {
console.log('User tokens found : ' + userTokens.token);
return userModule
.me(userTokens.token, uid)
.then((me) => {
return me;
}).catch((error) => {
return response.status(404).json({
data : {
error : 404,
message : 'NO_USER_ON_API'
}
});
})
}).catch((error) => {
console.log(error);
return response.status(404).json({
data : {
error : 404,
message : 'NO_TOKEN_USER_FOUND'
}
});
})
})
.catch((error) => {
console.log(error);
return response.status(500).json({
data : {
error : 500,
message : 'USER_TOKEN_NO_MATCH'
}
});
})
.then((user) => {
if(user.data !== undefined)
{
return response.status(200).json({
data : {
user : user.data
}
});
}
else
{
return response.status(204).json({
data : {
user : null
}
});
}
})
});
});
/* user.js */
exports.get = (firebaseToken) {
return admin.auth().verifyIdToken(firebaseToken)
.then(function(decodedToken) {
return decodedToken.uid;
})
.catch(function(error) {
throw {
code: 500,
body: "INTERNAL_ERROR"
};
});
};
exports.retrieve = (uid) {
return admin.firestore().collection("AccessTokenCollection").doc(uid).get()
.then(function(docRef) {
return docRef.data();
})
.catch(function(error) {
throw {
code: 404,
body: "NO_USER_FOUND"
};
});
};
exports.me = (UserToken, uid) {
let params = {
params: {
},
headers: {
'Authorization': 'Bearer ' + UserToken
}
};
return axiosInstance.instance.get(url + '/users/me', params)
.then(userMe => {
return userMe;
})
.catch(errMe => {
console.log(errMe.response.status);
throw {
code: 401,
body: "EXPIRING_TOKEN"
};
});
};
Etc...
The code works as it is more a theoretical question or optimization!
const userModule = require('./user');
exports.me = functions.https.onRequest((request, response) => {
cors(request, response, async () => {
let idToken = request.body.data.token;
try {
let uid = await userModule.get(idToken);
console.log('User found : ' + uid);
let userTokens = await userModule.retrieve(uid);
console.log('User tokens found : ' + userTokens.token);
let meObj = await userModule.me(userTokens.token, uid);
} catch (error) {
console.log('error', error);
}
});
});
So, here using async-await i have removed then-catch block. await keyword will work as then and will only move forward to second call after first call has been completed. And i have made a common catch block for error handling which you can modified according to your needs
you can use promise.all and async-await instead of then and catch

Send POST HTTP with ClaudiaJS and AWS Lambda

I building a service for push notifications in the facebook messenger. My nodejs app works fine in my localhost, but doesn't in AWS.
I use request module (npm) for send message.
My service can get the parameters, but doesn't send HTTP POST.
var ApiBuilder = require('claudia-api-builder'),
api = new ApiBuilder();
var request = require('request')
api.get('hello', function (req) {
var token = req.queryString.token;
var sender = req.queryString.sender;
var msg = req.queryString.msg;
messageData = {};
messageData.text = msg;
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: token },
method: 'POST',
json: {
recipient: { id: sender },
message: messageData,
}
}, function (error, response, body) {
if (error) {
return 'Error sending message: ' + error;
} else if (response.body.error) {
return 'Error: ' + response.body.error;
}
});
return sender + ' ' + messageData.text ;
})
module.exports = api;
You need to return a promise out of the API builder method handler for asynchronous operations. You can use something like got or minimal-request-promise to turn the HTTP request into a Promise, or just use a simple promise wrapper such as return new Promise((resolve, reject) => request(...., function (error, result) { if (error) { return reject(errror); else resolve(result) } }))
See item #4 in the guide on how to use external services from Claudia here: https://claudiajs.com/tutorials/external-services.html

Resources