I recently set up a supabase database and set up the client in my react app (I am using typescript with my react app). I am certain that I set up the keys for client and imported into my component correctly, because I successfully retrieved data from the database. However, when I attempt to add an api call to insert data, it doesn't work. Here is the function all from within my component, which I have linked up to a button and calling on click:
const createAccount = async () => {
console.log('in create');
const { data, error } = await supabase
.from('accounts')
.insert([
{ name: 'Test', type: 'test'},
])
console.log(error);
console.log(data);
}
I am also certain that the function is being called when I click the button (see by console.log('in create')). However, no data is being inserted to my database. When I console.log the error, I see simply 'FetchError: Failed to fetch' with no more details.
I have RLS disabled on my table, and my table is set to public. What is my data not being inserted?
Related
I am currently using a ReactJs frontend with the Firebase Javascript SDK. It is hooked up to a firebase-functions storage emulator using NodeJS in the backend.
Usually, I am able to call a functions.https.onCall(...) cloud function (that has been set up with nodejs) from my frontend and receive a promise, and then I can use the data in the front end normally.
However, using functions.storage.object().onFinalize(...) in the backend, I am trying to force some sort of way to return a success message to my front end after a file has successfully been processed.
Here is what I've tried:
My backend code (Nodejs):
exports.processMedia = functions.storage.object().onFinalize(async (object) =>{
// Here I successfully process any uploaded images
// Issue - After the media has been processed, I'd like to return a message that can be used to update the UI. I've tried to return a new promise like so:
return new Promise((resolve, reject) =>{
return resolve("Success");
});
})
And then in my React UI, I am trying to capture the return message from the backend using a httpsCallable('processMedia') function because I don't know how else to try to get the response.
async processMedia(){
const processMediaCallable = this.functions.httpsCallable('processMedia');
return processMediaCallable;
}
Then I try to log out the values from the promise:
async function getProcessedMessage(){
await firebase.processMedia().then((val) => {
console.log(val);
});
}
I get this output in the browser console for val after I've uploaded a file in the UI and processMedia() in the backend has completed:
ƒ (data) {
return _this.call(name, data, options || {});
}
I am trying to output a success message here. Any thoughts would be greatly appreciated. Thank you.
You cannot return a response to client from a background function. When a user uploads any file to your Firebase storage they get a success response and the function triggered from that event has nothing to do with client. There's a workaround for using Firebase Realtime Database which you can use to emit the response to user.
To break it down in simple steps:
Upload file to Firebase Storage
Create a realtime database listener on client side
After all processing in your Cloud Function, write something in the database and that'll be delivered to your user.
Client:
async function uploadFile() {
// upload to firebase storage
const alertRef = firebase.database().ref(`alerts/${userID}`);
alertRef.on('child_added', (snapshot) => {
const data = snapshot.val();
// Alert received from cloud function
// Delete this alert from database
snapshot.ref.set(null)
});
}
Cloud function:
exports.processMedia = functions.storage.object().onFinalize(async (object) => {
// Process the file
// Add alert in realtime database
const alertRef = firebase.database().ref(`alerts/${userID}`).push()
return alertRef.set({...}) // add any data you would like to pass to client side
})
child_added event is triggered once for each existing child and then again every time a new child is added to the specified path. The listener is passed a snapshot containing the new child's data.
That being said just make sure you are not alerting users multiple times with same notification.
Hi I'm fetching a arrays of posts from my express API in the Home.vue which is protected by route guards.
<script>
export default {
created() {
this.$store.dispatch('fetchPosts')
}
}
</script>
fetchPosts action:
async fetchPosts(context) {
try {
const res = await api.get('/posts', {
headers: {
Authorization: `Bearer ${localStorage.getItem('token')}`
}
})
context.commit('SET_POSTS', res.data)
context.commit('SET_ERROR', null)
} catch(err) {
console.log(err.response.data)
context.commit('SET_ERROR', err.response.data)
}
}
In my action I commit a mutation which sets the posts object to res.data. I only want to fetchPosts when user logs in since I have a mutation which adds the post to the db and updates the posts state, when user adds a post. But because I route back to the home screen this causes the created() hook to run again, re-fetching data on each post req. App of course work fine but could be more efficient. What can I do to resolve better enhance my app?
You could check that you do not already have the state populated.
If it's empty make the API call, otherwise do nothing.
Having guards is a good thing. Depending of your app and the way you want to handle authed users, you could also wire a global middleware to your router. This will add more generic code and could be used on several places, hence less errors/duplication.
Here is an interesting article about this: https://markus.oberlehner.net/blog/implementing-a-simple-middleware-with-vue-router/
The rest of your code looks fine!
When i am using the code below, i am getting an error :- cant find variable admin
admin.auth().getUserByEmail('svd#gmail.com')
.then(function(userRecord) {
// See the UserRecord reference doc for the contents of userRecord.
//console.log("Successfully fetched user data:", userRecord.toJSON());
alert(userRecord.toJSON());
})
.catch(function(error) {
console.log("Error fetching user data:", error);
})
Try doing this and tell me whether this works for you or not. I'm also not sure whether it's a fetch issue or DB issue from your firebase JSON data.
As far as this admin variable is concerned, it looks like it is a firebase instance, make sure that you initialize your firebase in your project correctly. Follow this link and add it to your project, then import or initialize it in your particular class where you want to fetch the details.
Add Firebase to your JavaScript Project
Thinking that you might have stored some of the data. Doing code like this would work :
firebase.auth().getUserByEmail('svd#gmail.com')
.then((response) => response.json())
.then((responseJson) => {
/* check the data is it coming in your console or you can simply put it inside the alert() */
console.log(responseJSon);
})
.catch((error) => {
console.log("Error fetching user data:", error);
});
Note: Before implementing that make sure you have initialized the admin variable in your code, else it won't be able to perform an operation on null variable or non-defined variable. Ensure that as well.
We're using the enterprise server side row model to fetch data from the server. We've implemented the IServerSideDatasource and, if the server errors, we call params.failCallback as recommended.
However, nothing happens on the grid. The loading spinner still is visible and there's no notification to the user about anything going wrong.
The 'onRowDataChanged' event fires, but it has no information about the status of the event.
Is there a recommended way to notify the user about the failure? Ideally I'd like to deal with this through ag-grid events rather than throw my own errors from the IServerSideDatasource or even the http client.
Is this possible?
I'm using a custom eventListener to catch failCallback calls and it works pretty well
In my main class:
onGridReady = params => {
this.gridApi = params.api;
this.gridApi.addEventListener('failCallback', this.onServerFailCallback);
this.gridApi.setServerSideDatasource(MyRemoteDataSource);
};
onServerFailCallback = params => {
console.error('onServerFailCallback', params);
}
In MyRemoteDatasource:
class MyRemoteDatasource{
getRows(params) {
fetchData(params).then(
response => {
params.successCallback(response.data);
},
error => {
params.failCallback();
params.parentNode.gridApi.dispatchEvent({
type: 'failCallback',
api: params.parentNode.gridApi,
columnApi: params.parentNode.columnApi,
error: error
});
});
}
}
output:
onServerFailCallback,
{type: "failCallback", api: GridApi, columnApi: ColumnApi, error: Error: Error inside fetchData() at stack trace…}
I am having the logged in user make some changes on itself. These changes happen in the cloud function called by the client code. The cloud code executes correctly and returns back after which I query the user table to get the updated data but it gives back old data and the updated fields are missing. Using the latest available parse-latest.js from CDN.
I have already tried sending the users session token in the save call and also the useMasterKey but no change in behaviour.
Steps to reproduce
Call a cloud function that changes a field for the currently logged in User
Once cloud function has completed and returned to client side query the user table to get latest data.
If you check this data is stale data and does not include the latest data.
Here is the sample code
This is the call to the cloud function which is inside a promise.
Parse.Cloud.run("notification_update", params))
.then(function(obj) {
dfd.resolve(obj);
}, function onError(err) {
console.error(err)
dfd.reject(err);
}
The relevant code in cloud function
currentUser.set("team", team);
console.log("Session token ");
console.log(currentUser.getSessionToken());
promises.push(currentUser.save(null, { sessionToken: currentUser.getSessionToken() }));
Once the cloud function returns I call this function. I check in the parse DB the data is updated.
var refresh = function onRefresh(dfd) {
console.debug("Refresh user was triggered..");
var currentUser = Parse.User.current();
var q = new Parse.Query(Parse.User);
q.include("team");
q.get(currentUser.id)
.then(function success(user) {
currentUser.set({
team: user.get("team"), //Here the data is not updated
});
if (dfd && dfd.resolve) {
dfd.resolve(currentUser);
}
}, function onError(error) {
if (dfd && dfd.reject) {
dfd.reject(error);
}
});
}
Additionally when I check the response from the server in my Network tab in Chrome, I see that the user has all the updated data.
Why don't you just do a query against the user (me) instead of running a full pledged query to fetch the user.
Parse.User.become(sessionToken).then(function(user){
//User Object is available to you here
})