Firebase multi location update, delete redundant data as part of update - javascript

I'm using firebase multi location updates to update a number of locations in my database.
One of the update paths contains a value that could be changed as part of the update therefore creating a new record at the new path location which is correct. This then leaves a redundant data at the original location that I need to delete as part of the update. Can someone give me a pointer on how to delete the redundant data as part of the update?
I am using the code below to create my update: -
var updatedUserDataContent = {
title: $scope.postToUpdate.title
commenter: $scope.postToUpdate.commenter
};
updatedUserData["Posts/" + $scope.postToUpdate.$id] = updatedUserDataContent;
updatedUserData["UserPosts/" + $scope.postToUpdate.commenter + "/" + $scope.postToUpdate.$id] = updatedUserDataContent;
The commenter could be changed by a user on the record before saving leaving the redundant data in the original commenter node. I have tried using the security rules but these stop data being created rather than deleted.
Edit 1
JSON as requested.
Before the update I have
{
"Not assigned" : {
"-KNfs3OhBmbb93w9VEW-" : {
"title": "vytg",
"commenter": "Not assigned"
}
}
}
After the update (after changing commenter from "Not assigned" to "User A") I have
{
"Not assigned": {
"-KNfs3OhBmbb93w9VEW-": {
"title": "vytg",
"commenter": "Not assigned"
}
},
"User A" : {
"-KNfs3OhBmbb93w9VEW-" : {
"title": "vytg",
"commenter": "User A"
}
}
}
but I want just
{
"User A" : {
"-KNfs3OhBmbb93w9VEW-" : {
"title": "vytg",
"commenter": "User A"
}
}
}

You're trying to move/rename a node, which is not an operation the database supports.
Since the new data is written correctly, all that is needed is that you also clear out the old node. Putting null in for that location will take care of that:
updatedUserData["Not assigned"] = null;

Related

Firestore document update using REST api

I'm trying to increment one value in firebase store using rest api following this guide https://firebase.google.com/docs/firestore/reference/rest/v1beta1/projects.databases.documents/commit
I'm trying to make the request using the form given at this documentation.
Here's my path to the document
/hindiscript-likes/kof97lbQ1IuuvgCHBfOh
where hindiscript-likes is the collection name.
The document looks like below
Here's my request body
{
"writes": [
{
"transform": {
"document": "projects/public-api-07/databases/(default)/documents/kof97lbQ1IuuvgCHBfOh",
"fieldTransforms": [
{
"increment": {
"integerValue": 1
}
}
]
}
}
]
}
But upon executing this, it is returnng 400 with the following error
{
"error": {
"code": 400,
"message": "Document name \"projects/public-api-07/databases/(default)/documents/kof97lbQ1IuuvgCHBfOh\" lacks \"/\" at index 73.",
"status": "INVALID_ARGUMENT"
}
}
Can somebody help ?
You're missing the name of the collection in the path of the document to update. What you have now is asking for just "kof97lbQ1IuuvgCHBfOh", which it assumes is the name of a collection but a missing document ID. But what you want instead is "hindiscript-likes/kof97lbQ1IuuvgCHBfOh".
Try:
"document": "projects/public-api-07/databases/(default)/documents/hindiscript-likes/kof97lbQ1IuuvgCHBfOh",

Matching query images with JSON variable in Gatsby

So, I have a JSON file that has info I'm pulling into my React project. One of those fields is an image keyword. I want to use that to call images in a "show" folder where promo images can be dumped.
thisYear.json
{
"title": "Rope",
"author": "Patrick Hamilton",
"image": "rope",
},{
"title": "I Hate Hamlet",
"author": "Paul Rudnick",
"image": "iHateHamlet",
}
]
I made a query that is grabbing the images from said "show" folder to the jsx file
{
allFile(filter: {relativeDirectory: {eq: "shows"}}) {
edges {
node {
id
name
childImageSharp {
gatsbyImageData(placeholder: DOMINANT_COLOR)
}
}
}
}
}
I've tried to write some functions that compare the name properties, but I just can't seem to write anything that works. I'm not grasping something here and I just don't know what it is.
The showImage is passed in while I'm mapping through my JSON file and comparing with imageData, which is the query data. The console log is showing the right names being compared, so I know it's passing through. it's just not passing that data to the GatsbyImage.
function findImage(showImage) {
imageData.map((image) => {
console.log(image.node.name + ' vs ' + showImage)
if (image.node.name == showImage) {
/**if the image name == our show image name, we return that image data */
return data.file.childImageSharp.gatsbyImageData
}
})
return
}
My git repository is here if it helps:
https://github.com/TheComeBackGuy/TKD-Gatsby
Well, I figured out what I was doing wrong. I wasn't returning the answer to the root of the function. I'm sure a more experienced person could write it cleaner, but here's what I used.
export default function FindImage(queryArray, showImage) {
let returnStatement = null
queryArray.map((images) => {
if (images.node.name == showImage) {
console.log(showImage + ' vs ' + images.node.name)
console.log(images.node.childImageSharp.gatsbyImageData)
returnStatement = images.node.childImageSharp.gatsbyImageData
}
})
return returnStatement
}

Firebase retrieve data when certain child value within child changes

So I have a firebase realtime database which keeps users messages. At the moment I have it so when a users 'inbox' child is updated it retrieves the latest data for that child, for example:
firebase.database().ref('users/'+firebase.auth().currentUser.uid+'/inbox/').on('child_changed', function(snapshot) {
// get the latest data
});
But when using this method, if a message is deleted by the user, it will retrieve the child data again. Is there anyway to only retrieve the latest data only if a child inside of that child is updated?
So in my database I have it set out like this:
{
"users" : {
"IPenCEXKICROYWzYtyzybzhem9R2" : {
"inbox" : {
"32tcqIRaG2RAgb9dTwmcgKoVPhd2IPenCEXKICROYWzYtyzybzhem9R2" : {
"lastmessagetimestamp" : 1564139876817,
"conversationmessages" : {
"-LhKZ-MUVxbyRcqp-Q_c" : {
"from" : "32tcqIRaG2RAgb9dTwmcgKoVPhd2",
"messagetext" : "this is a test message",
}
},
},
},
},
}
}
I am saving that timestamp of the last message a user receives. So I would like it to only retrieve data if the 'lastmessagetimestamp' child value is changed.
The simplest way I could think of doing this would be:
firebase.database().ref('users/'+firebase.auth().currentUser.uid+'/inbox/**conversationid**/lastmessagetimestamp/').on('child_changed', function(snapshot) {
// get the latest data
});
But because my 'conversationid' is randomly generated and is not unique, it cannot be done. Is there a way to possibly skip the 'conversationid' and go directly to the 'lastmessagetimestamp'?

What is wrong with my JSON output for a Slack Message payload?

I have set up what I think should be a working JSON output to send a message in slack but Slack keeps rejecting it.
I have tried multiple different message layout formats using the guides on slack's api site, but so far the only method that has successfully sent is a fully flat JSON with no block formatting.
function submitValuesToSlack(e) {
var name = e.values[1];
var caseNumber = e.values[2];
var problemDescription = e.values[3];
var question = e.values[4];
var completedChecklist = e.values[5];
var payload = [{
"channel": postChannel,
"username": postUser,
"icon_emoji": postIcon,
"link_names": 1,
"blocks": [
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Name:*\n " + name
}
]
}]
}];
console.log(JSON.stringify(payload, null, "\t"));
var options = {
'method': 'post',
'payload': JSON.stringify(payload)
};
console.log(options)
var response = UrlFetchApp.fetch(slackIncomingWebhookUrl, options);
}
When I run this, I get the following output:
[
{
"channel":"#tech-support",
"username":"Form Response",
"icon_emoji":":mailbox_with_mail:",
"link_names":1,
"blocks":[
{
"type":"section",
"fields":[
{
"type":"mrkdwn",
"text":"*Name:*\n test"
}
]
}
]
}
]
Which I believe is correct, however slack api just rejects it with an HTTP 400 error "no text"
am I misunderstanding something about block formatting?
EDIT:
To Clarify, formatting works if I use this for my JSON instead of the more complex format:
{
"channel":"#tech-support",
"username":"Form Response",
"icon_emoji":":mailbox_with_mail:",
"link_names":1,
"text":"*Name:*\n test"
}
The reason you are getting the error no_text is because you do not have a valid message text property in your payload. You either need to have a text property as top line parameter (classic style - your example at the bottom) or a text block within a section block.
If you want to put to use blocks only (as you are asking) the section block is called text, not fields. fields is another type of section bock that has a different meaning.
So the correct syntax is:
[
{
"channel":"#tech-support",
"username":"Form Response",
"icon_emoji":":mailbox_with_mail:",
"link_names":1,
"blocks":[
{
"type":"section",
"text":[
{
"type":"mrkdwn",
"text":"*Name:*\n test"
}
]
}
]
}
]
Also see here for the official documentation on it.
Blocks are very powerful, but can be complicated at times. I would recommend to use the message builder to try out your messages and check out the examples in the docu.

Rest API Patch only 1 field at a time

I'm working on an inline grid editor that calls an express rest api after a single value in the grid is updated. So when a user changes a single field in the grid, I am calling a PATCH request to update the field. However I can't figure out how to only update a single field. When I try it tries to update them all and if there's no value it makes the value NULL in the database. I want to only update a single field, and only the one passed into the API (it could be any of the fields). Here's my method to patch:
// Update record based on TxnID
router.patch('/editablerecords/update', function (req, res) {
let qb_TxnID = req.body.txnid
let type = req.body.type;
let margin = req.body.margin;
if (!qb_TxnID) {
return res.status(400).send({ error:true, message: 'Please provide TxnID' });
}
connection.query("UPDATE pxeQuoteToClose SET ? WHERE qb_TxnID = '" + qb_TxnID + "'", { type, margin }, function (error, results, fields) {
if(error){
res.send(JSON.stringify({"status": 500, "error": error, "response": null }));
//If there is error, we send the error in the error section with 500 status
} else {
res.send(JSON.stringify({ error: false, data: results, message: 'Record updated.' }));
//If there is no error, all is good and response is 200OK.
}
});
});
I will only be updating 1 field at a time, either type or margin, but not both (in this case) at the same time. If I only send one of the fields, the other field becomes null. I've tried to read up on the connection.query() method but can find no information and I don't understand how it builds the query, except that every req.body.value that is passed to it gets used to build the query.
I'm new to building this REST API and feel like I'm missing something simple.
EDIT: I'd like to add, I MAY want to update both fields, but I'd also like to update a single field at a time. Thanks
Per the RFC, the body of a PATCH call should not be the updated representation, but rather a set of instructions to apply to the resource.
The PATCH method requests that a set of changes described in the
request entity be applied to the resource identified by the Request-
URI. The set of changes is represented in a format called a "patch
document" identified by a media type.
One good proposed standard for using PATCH with JSON can be found at https://www.rfc-editor.org/rfc/rfc6902. An example patch document using that standard would be:
[
{ "op": "test", "path": "/a/b/c", "value": "foo" },
{ "op": "remove", "path": "/a/b/c" },
{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
{ "op": "replace", "path": "/a/b/c", "value": 42 },
{ "op": "move", "from": "/a/b/c", "path": "/a/b/d" },
{ "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
]

Categories

Resources