Trying to submit an update to a firebase document - keep getting errors stating that the document ID isn't available. Unsure how to fix the problem exactly.
The firebase call is this,
exports.updateWorkflow = (req, res) => {
let Workflow = req.body;
db.doc(`/Workflow/${req.params.WorkflowId}`)
.update(Workflow)
.then(() => {
return res.json({ message: "Details added successfully" });
})
.catch(err => {
console.error(err);
return res.status(500).json({ error: err.code });
});
};
Route is,
app.post('/updateWorkflow', updateWorkflow);
And using postman i'm submitting
http://localhost:5000/xx/xx/api/updateWorkflow/3ejAQxPoJ6Wsqsby01S6
With a json body of
{
"claimEoT" : "false"
}
{ Error: 5 NOT_FOUND: No document to update: ...../Workflow/undefined
> at Object.callErrorFromStatus (....
> code: 5,
> details: 'No document to update: p.......',
> metadata: Metadata { internalRepr: Map {}, options: {} } }
I am trying to make it so I can update the data in the document. It is being used in a wizard form to save state, so basically when I change a variable in the form from true to false, the state changes, and when I click submit, the changes are updates in the document on firebase.
I think it's something to do with how I am creating the firebase call - or something to do with the information I am sending to the call. Very confused - feel like it should be working really
Needed to change url to include ../:workflowId
Related
I have to write a firebase function that receives a JSON with a list of users and has to manage them with the following rules. For each user in the received list:
If the user is already registered (email/password) in firebase, I update it.
If the user is not registered yet, I create it
If a user is registered in firebase but it's not present in the received list, I disable it.
Now, I came up with the following solution: I iterate for each user in the received list. I call admin.auth().createUser() method so that if the user is not registered it will be created, otherwise the method throws an error and in the catch() block I call admin.auth().updateUser().
For the second part, I retrieve all the users registered with admin.auth().listUsers() and for each of them I check whether it's present in the received list: if don't so, I disable it.
For some reason, the correctness of this solution is uncertain: sometimes it doesn't work at all, other times when I call the function once it doesn't work but the second time a call the function it works, idk why is that.
This only happens when I send to the function a lot of users (about 400). If I send only few users it works fine.
Could anyone suggest to me maybe a better solution? Thanks a lot for your answer.
This is the function:
exports.addClients = functions.https.onRequest(async (req, res) => {
// fetch recevied list from payload
var receivedClients = req.body.clients;
// create or update user
receivedClients.forEach(client => {
admin.auth().createUser({
uid: client.id,
email: client.email,
emailVerified: true,
password: client.password,
})
.catch(err => {
// update user
admin.auth().updateUser(client.id, {
email: client.email
}).catch(err => {
// error updating user
log("Error updating user: " + err);
});
})
});
// disabling users not present in the received list
listUsers = await admin.auth().listUsers();
userRecords = listUsers.users;
userRecords.forEach(record => {
if (!receivedClients.some(client => client.id === record.uid)) {
// disable user
admin.auth().updateUser(record.uid, {
disabled: true
})
.catch(err => {
// error disabling user
log("Error disaling user: " + err);
});
}
});
// send response
res.sendStatus(200);
});
I am trying to delete data from my app both in the database and UI, but I am a
bit confused on how to request this action from react.js using axios. I have
created a method call which I assigned to an event handler on the elements
'delete' button within my react app but continue to get a message of 'null' in
the terminal. I suppose this is the app telling me that it cannot find the
element I am trying to delete and would greatly appreciate it if someone could
point me in the right direction or give me some pointers on how to fix errors I
may have made along the way.
Below is my react code
state = {
title: '',
body: '',
posts: []
}
deleteBlogPosts = () => {
axios.delete(`/api/delete`)
.then((response) => {
console.log(`${response} request deleted`)
})
.catch((err) => {
console.log(err.response)
})
}
displayBlogPosts = (posts) => {
if(!posts.length) return null
return posts.map((post, index) => (
<div className='blog' key={index}>
<h1>{post.title}</h1>
<h5>{post.body}</h5>
<button onClick={this.deleteBlogPosts()}>delete</button>
</div>
))
}
MY API file with the endpoints
router.delete('/delete', (req, res) => {
Blog.findOneAndRemove({
_id: req.params.Id
}, (err, data) => {
console.log(data)
if(err) {
res.status(500).json({
msg: 'Houston we have a problem'
})
return
}return res.json({
msg: 'Data was received'
})
})
})
Hey everyone thanks for those who attempted to help. Shortly after posting, I realized that I had unnecessary parameters within my 'delete' endpoint. I also found out that I failed to include the ID in the endpoint URL. SO happy that I got it taken care of.
Note - The following error occurs only for the first time click of my application's "submit" button and only on the first load of page. If I click on "submit" button again, it works perfectly fine.
For fetching data from an API I am using axios.all and in order to authorize the JQL queries I need username and password. An authorization string (this.setState{authString}) is set before calling axios.all and inside each of these get calls, I use my this.state.authString for authorization.
onSubmit = (event) => {
event.preventDefault();
event.stopPropagation();
let iNumber = event.target.iNumber.value;
let pass = event.target.password.value;
let query = CURRENT_SPRINT_INFO;
if (!iNumber || !pass || !query) {
alert("Enter Valid iNumber, password and sprint info");
return;
}
this.loadData(iNumber, pass, query);
}
loadData = (iNumber, pass, query) => {
notify.show("Loading...", "warning", 500);
const authString = "Basic " + btoa(iNumber + ":" + pass);
this.setState({
authString: authString,
loading: true
});
axios.all([this.getBacklogItemsData(query), this.getBugsData(query), this.getWaveItemsData(query)])
.then(axios.spread((backlogItems, bugs, waveTasks) => {
notify.show("data Loaded successfully", "success", 3000);
const { adhocIssues, scrumBoardIssues } = this.getSeparateBIItems(backlogItems.data.issues);
this.setState({
adhocIssues: [...adhocIssues],
scrumBoardIssues: [...scrumBoardIssues],
bugs: [...bugs.data.issues],
waveBoardTasks: [...waveTasks.data.issues],
loading: false
})
// set session variables
setUserDetails(iNumber, pass);
}))
.catch(error => {
notify.show(`Error occurred while fetching data`, "error", 3000);
this.setState({ loading: false });
throw new error(error);
})
}
On first load of page and on click of my submit button, it throws Error: request failed with status code 401: Unauthorized -> and when I debug and check, the authString is empty i.e. authString = "" -> this happens on my first GET call itself (i.e. inside this.getBacklogItemsData(query))
Once I click on my submit button again, it works perfectly fine
Inspired from: https://codesandbox.io/s/rm4pyq9m0o
For fetching data from an API I am using axios.all and in order to authorize the JQL queries I need username and password. An authorization string (this.setState{authString}) is set before calling axios.all and inside each of these get calls, I use my this.state.authString for authorization.
In event handlers react flushes all the state changes only when you exit the event handler.
Here I set up an example
https://codesandbox.io/s/runtime-firefly-v59yk
So during the execution of the event handler when you access this.state.authString it gives you the initial value with which you entered
the event handler.
So one way to solve the issue would be to use the second argument of setState to make sure state has been updated and component has been rerendered, like this
this.setState({
authString: authString,
loading: true
}, () => axios.all(...));
Because this.setState is async. So you can use callback with setState like this:
this.setState({
authString: authString,
loading: true
}, () => {
axios.all(...) // Call axios here to make sure setState done
});
More information, check docs setState here
I have an app for todos. I'm trying to update a specific todo within an array of todos stored in the User I'm currently logged into. This is the code that does that:
User.findById(req.user._id)
.then(user => {
user.todos.forEach(function(todo) {
if (todo._id == req.params.todoId) {
todo.completed = !todo.completed;
console.log(todo.completed);
}
})
return user.save();
})
.then(result => {
console.log(result);
res.json(result);
})
.catch(function(err) {
res.send(err);
})
When I console.log the result, everything comes out fine. When I console log the updated Todo in the ajax call I'm making in my javascript file, everything appears fine. The todo is updated. However, when I stop my server and find the user in Mongo, the todo still isn't updated.
Any help is much appreciated.
When you modify a nested property on a document, mongoose may not be aware that anything changed, so it won't know to persist the changes in the DB (otherwise it would have to pass everything, which could become expensive if you have a large document but only a tiny part of it changed).
This can be done via the markModified method:
user.todos.forEach(function(todo) {
if (todo._id == req.params.todoId) {
todo.completed = !todo.completed;
console.log(todo.completed);
}
})
user.markModified('todos');
return user.save();
Instead of doing it in JavaScript code I will suggest you can do it in query only which will more effective.
db.getCollection('User').update({"_id":<req.user._id>,"todo._id":<req.params.todoId>},
{$set:
{'todo.$.completed': true}
}, {
new : true
}
)
In this query you need to pass completed status as well.
While i click on the login button i get this error :
[19:49:11] [2018-12-25T20:49:57.389Z] #firebase/database:, FIREBASE
FATAL ERROR: Cannot parse Firebase url. Please use https://<YOUR
FIREBASE>.firebaseio.com
- node_modules/#firebase/logger/dist/index.cjs.js:69:32 in
defaultLogHandler
- node_modules/#firebase/logger/dist/index.cjs.js:159:31 in error
- node_modules/#firebase/database/dist/index.cjs.js:333:20 in fatal
- node_modules/#firebase/database/dist/index.cjs.js:1256:14 in
parseRepoInfo
- node_modules/#firebase/database/dist/index.cjs.js:15103:38 in
refFromURL
* src/modules/auth/api.js:24:24 in getUser
* src/modules/auth/api.js:19:32 in <unknown>
- node_modules/#firebase/auth/dist/auth.js:17:105 in <unknown>
- node_modules/#firebase/auth/dist/auth.js:20:199 in Fb
- ... 13 more stack frames from framework internals
I copied and pasted the config stuff directly from Firebase, so it should be correct, but I get this error anyway. What could be causing this? Is there any way the URL I'm copying from my database could be wrong somehow?
As you you can see in the error shown are in my file api.js in
.then((user) => getUser(user, callback))
and in
database.refFromURL('users').child(user.uid).once('value')
So here is my code from api.js is like this :
import { auth, database, provider } from "../../config/firebase";
export function register(data, callback) {
const { email, password } = data;
auth.createUserWithEmailAndPassword(email, password)
.then((user) => callback(true, user, null))
.catch((error) => callback(false, null, error));
}
export function createUser (user, callback) {
database.refFromURL('users').child(user.uid).update({ ...user })
.then(() => callback(true, null, null))
.catch((error) => callback(false, null, {message: error}));
}
export function login(data, callback) {
const { email, password } = data;
auth.signInWithEmailAndPassword(email, password)
.then((user) => getUser(user, callback))
.catch((error) => callback(false, null, error));
}
export function getUser(user, callback) {
database.refFromURL('users').child(user.uid).once('value')
.then(function(snapshot) {
const exists = (snapshot.val() !== null);
if (exists) user = snapshot.val();
const data = { exists, user }
callback(true, data, null);
})
.catch(error => callback(false, null, error));
}
can anyone please help where i missed up
i used
database.ref(`users/`+user.uid).once('value')
instead of
database.refFromURL('users').child(user.uid).once('value')
and it works fine for me now.
Please go through this documentation and update to new modular type or if you want to use old structure then, update to
<script src="https://www.gstatic.com/firebasejs/8.5.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.5.0/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.5.0/firebase-database.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.5.0/firebase-storage.js"></script>
update all to version 8.5.0. Will work flawless
The refFromURL method expects a fully qualified URL to the database. So something starting with https://<YOUR
FIREBASE>.firebaseio.com as the error message shows.
You're trying to access a path within the configured database, in which case you should use ref(...) instead:
database.ref('users').child(user.uid).once('value')
I think there are mainly two types of realtime db urls , one ends with ".firebaseio.com" which is for US and other like EU and asia have url which ends with "firebasedatabase.app"
"Please use https://.firebaseio.com", this error comes at line when u call firebase.database(), It can happen that firebase library or module you are using are of old versions which can only make call for db whose url ends with firebaseio.com,
so make sure to update it,
or you can just change the region of your realtime database to US region.