How to add fields to new document onCreate? - javascript

I'm trying to add new fields to a new document after calculation, that I have to do when a new doc is created. But, the field isn't added.
I have deploy this code without any errors but when a new doc is added in this path, nothing happens..
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const db = admin.firestore();
exports.test = functions.firestore.document('a/{a.id}/b/{b.id}/c/d')
.onCreate(async(snapshot, context) => {
const data = snapshot.data();
const userRef = db.doc(`a/${a.id}/b/${b.id}/c/d`);
var result = 1+2; //just for lighter code example
return userRef.update({
result: result
});
})

Your wildcards are invalid. You can't have a dot in the wildcard name. I'm kind of surprised that the Firebase CLI allowed you to deploy this function. Also, you're not using the wildcards correctly, even if those wildcards were valid.
There is an easier way to get a reference to the document that was just created. You can use snapshot.ref.
exports.test = functions.firestore.document('a/{a}/b/{b}/c/d')
.onCreate(async(snapshot, context) => {
var result = 1+2; //just for lighter code example
return snapshot.ref.update({
result: result
});
})
If you do want to use the wildcard values, you should use context.params instead, as described in the documentation.

Related

ETH ENS Web3 - How to get Registrant

I've following code snippet to get the "Controller" (The owner of the domain) but I need to get the "Registrant" of provided ENS name
const Web3 = require("web3")
const web3 = new Web3("https://cloudflare-eth.com");
var ens = web3.eth.ens;
var names = ['jtimberlake.eth', 'usman.eth'];
(async () => {
for (let domainName of names) {
// console.log('checking: ' + domainName);
const addr = await getDomain(domainName);
console.log(addr);
}
})();
async function getDomain(word) {
try {
const addr = await ens.getAddress(`${word}`)
// console.log(addr);
return addr;
} catch (err) {
console.error(err);
return;
}
}
Can you please guide how I can get the "Registrant" of provided ENS name e.g. jtimberlake.eth
Web3 is a steaming pile. It doesn't do it with its methods. The registrant used to be called the deed owner, and the controller the owner. Now it is registrant and controller. That's why the method name makes no sense at all now in Web3.js - it never got updated, and never was useful for this in the first place.
The good news is there is a simple way. You can derive the token ID of the ENS domain from its name with the getRegistrant function below. https://docs.ens.domains/dapp-developer-guide/ens-as-nft
The name variable in the docs is superfluous and does nothing. You will need to instantiate ethersjs (npm install ethers) to get the ethers methods to work. You have to use this crazy number of functions because the token ID of an ENS domain/NFT is a uint256. JavaScript hates those natively.
The web3 method to find the controller also still works well if you ever need that. I suggest putting it in another function.
const getRegistrant = (domainName) => {
const BigNumber = ethers.BigNumber
const utils = ethers.utils
const labelHash = utils.keccak256(utils.toUtf8Bytes(domainName))
const derivedTokenId = BigNumber.from(labelHash).toString()
//You need to instantiate the ENSRegistrarContract with its ABI and address. e.g. const ENSRegistrarContract = new web3.eth.Contract(ABI, ADDRESS)
ENSRegistrarContract.methods.ownerOf(derivedTokenId).call()
.then(function(registrant) {
console.log(domainName + "is owned by: " + registrant)
return registrant
})
}
const getController = (domainName) => {
//getOwner fetches the controller of a domain confusingly.
web3.eth.ens.getOwner(domainName).then(function(controller) {
console.log(domainName + "is controlled by: " + controller)
return controller
})
}

AWS Lambda - Only getting answer after the second test trigger

I'm developing an AWS Lambda in TypeScript that uses Axios to get data from an API and that data will be filtered and be put into a dynamoDb.
The code looks as follows:
export {};
const axios = require("axios");
const AWS = require('aws-sdk');
exports.handler = async (event: any) => {
const shuttleDB = new AWS.DynamoDB.DocumentClient();
const startDate = "2021-08-16";
const endDate = "2021-08-16";
const startTime = "16:00:00";
const endTime = "17:00:00";
const response = await axios.post('URL', {
data:{
"von": startDate+"T"+startTime,
"bis": endDate+"T"+endTime
}}, {
headers: {
'x-rs-api-key': KEY
}
}
);
const params = response.data.data;
const putPromise = params.map(async(elem: object) => {
delete elem.feat1;
delete elem.feat2;
delete elem.feat3;
delete elem.feat4;
delete elem.feat5;
const paramsDynamoDB = {
TableName: String(process.env.TABLE_NAME),
Item: elem
}
shuttleDB.put(paramsDynamoDB).promise();
});
await Promise.all(putPromise);
};
This all works kind of fine. If the test button gets pushed the first time, everything seems fine and is working. E.g. I received all the console.logs during developing but the data is not put into the db.
With the second try it is the same output but the data is successfully put into the Db.
Any ideas regarding this issue? How can I solve this problem and have the data put into the Db after the first try?
Thanks in advance!
you need to return the promise from the db call -
return shuttleDB.put(paramsDynamoDB).promise();
also, Promise.all will complete early if any call fails (compared to Promise.allSettled), so it may be worth logging out any errors that may be happening too.
Better still, take a look at transactWrite - https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#transactWrite-property to ensure all or nothing gets written

Delete image from url Firebase Storage

In my cloud functions, I'm trying to delete an image based on its url, but I think that I don't use correctly the API as I'm getting errors :
const admin = require('firebase-admin');
exports.deleteImageWhenOfferDeleted = functions.firestore
.document('offers/{offerId}')
.onDelete(async(snap, context) => {
console.log('----------------start function--------------------')
const deletedOffer = snap.data();
var imageUrlToDelete = deletedOffer.imageUrl;
await admin.storage.getPathStorageFromUrl(imageUrlToDelete).delete();
function getPathStorageFromUrl(url){
const baseUrl = "https://firebasestorage.googleapis.com/v0/b/muslim-coloc.appspot.com/o/";
let imagePath = url.replace(baseUrl,"");
const indexOfEndPath = imagePath.indexOf("?");
imagePath = imagePath.substring(0,indexOfEndPath);
imagePath = imagePath.replace("%2F","/");
return imagePath;
}
I think you're missing brackets after storage word.
You need to get an instance of storage object.
admin.storage.getReferenceFromUrl(...)
should be
admin.storage().getReferenceFromUrl(...)
BTW: Consider using TypeScript, because it catches errors like that during compilation.

Does MongoDB Stitch Functions support async/await definitions?

Asynchronous function definitions on MongoDB (Atlas) Stitch display warnings on the GUI editor. Including the example code provided on the reference for Triggers.
The code found here can be was copied over directly to the Stitch Function editor and produces warnings because of the async keyword.
Example code from the docs.
exports = async function (changeEvent) {
// Destructure out fields from the change stream event object
const { updateDescription, fullDocument } = changeEvent;
// Check if the shippingLocation field was updated
const updatedFields = Object.keys(updateDescription.updatedFields);
const isNewLocation = updatedFields.some(field =>
field.match(/shippingLocation/)
);
// If the location changed, text the customer the updated location.
if (isNewLocation) {
const { customerId, shippingLocation } = fullDocument;
const twilio = context.services.get("myTwilioService");
const mongodb = context.services.get("mongodb-atlas");
const customers = mongodb.db("store").collection("customers");
const { location } = shippingLocation.pop();
const customer = await customers.findOne({ _id: customer_id })
twilio.send({
to: customer.phoneNumber,
from: context.values.get("ourPhoneNumber"),
body: `Your order has moved! The new location is ${location}.`
});
}
};
I want to know if Stitch supports the async/await paradigm and if I should be concerned about the warnings shown.
After some testing I found that at this time the async/await keywords cause the linter to throw errors and warnings. This means that for async callbacks it is best to define them separately as it will improve the linting. IE. [].map(async () => {}) will prompt errors that can be worked around.
The runtime execution returns the results as expected from standard asynchronous operations.

Firebase Firestore Cloud Function Never Execute

I made Firestore Could Function Where I have Database Like this
'posts/{postId}/comments/{commentId}'
and Function I made To Increase Field In PostId when New Comment Added
the Funtion has Deploy But it`s Never Execute when adding New Comment
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.comment= functions.firestore
.document('posts/{postId}/comments/{commentId}')
.onWrite((change, context) => {
const commentId = event.params.commentId;
const postId = event.params.postId;
const docRef = admin.firestore().collection('posts').doc(postId);
return docRef.update({numberOfComments:200});
});
I Added Many Comment Even Executions is 0
change this:
const commentId = event.params.commentId;
const postId = event.params.postId;
into this:
const commentId = context.params.commentId;
const postId = context.params.postId;
more info here:
https://firebase.google.com/docs/functions/beta-v1-diff
Before Firebase SDK (<= v0.9.1) version event.params.id was worked. but Now (v1.0.0) android provide documentation to use context.params.id.
Use context insted of event, your problem will be solve.
const commentId = event.params.commentId;
const postId = event.params.postId;
Thanks.

Categories