Get unique Key from Firebase Database - node.js

I am writing to the RealTime Database using a db file. The field generates a unique id key and I need to pass that key back to the parent file.
My db function:
export const doCreateCompany = name =>
db
.ref(`company`)
.push()
.set({ name });
My calling function is as follows:
db.doCreateCompany(companyName).then((e) => {
console.log("Key", e);
I need to write another function immediately following using the unique key. Any help is great. Thanks

If you want your function to still return a promise that resolves when the set() is complete, and also have access to the push ID, try something like this:
export const doCreateCompany = name => {
const ref = db.ref('company').push()
return ref.set({ name }).then(() => {
return Promise.resolve(ref.key)
})
}
Then you can call it like this:
doCreateCompany(name).then(key => {
// key is the push id here
})

You can separate the call to push() from the set(...):
export const doCreateCompany = name =>
var ref = db.ref(`company`).push();
var key = ref.key;
ref.set({ name });
Now you can return the key to whoever called the function.

Related

firestore not updating results

I am working with firestore in NodeJS, and wrote the function below, this function receives the results array as a parameter, which contains the firestore doc id that needs to be updated.
So, for each document, i am calling the set method to add the fileName field to this document. But for some reason, the result only updated when i have a single id in this results array.
Can someone help me?
async function update(results, fileName) {
results.forEach(data => {
let id = firestore.collection('My_collection').doc(data.DOC_ID)
id.set(
{ filename: fileName}, {merge:true}
)
})
}
You can try by adding a promise to your code.
async function update(results, fileName) {
results.forEach(data => {
let id = firestore.collection('My_collection').doc(data.DOC_ID)
await id.set({ filename: fileName}, {merge:true})
})
}
Like shown in the documentation[1]
[1]https://firebase.google.com/docs/firestore/quickstart#add_data

I want to return data from dynamodb when the key matches

**I want to return the data key values but it is not working. Please help me. The main concept of this method is when this is invoke dal is the keyword and it fetches that key values from the dynamodb. For that i used global also but not updating that global variable also.
I tried returning the value from the callback, as well as assigning the result to a local variable inside the function and returning that one, but none of those ways actually return the response (they all return undefined or whatever the initial value of the variable result is).**
function getLocation(){
let a=[];
const documentClient = new AWSS.DynamoDB.DocumentClient({region:"us-east-2"});
const params = {
TableName : "ProductLocation1",
Key :{
Product_Name : 'dal'
}
};
documentClient.get(params,(err,data)=>{
if(err){
console.log('error is',err);
}
console.log('data is : ',data);
global.a=Object.keys(data);
});
return global.a;
}
try {
const result = await documentClient.get(params).promise();
} catch (error) {
// handle error
}
You could get the result using the promise & await rather than the callback function. In this way, you don't need to store them in a local variable.

How to instantiate Dynamoose Model from DynamoDB's AttributeValue format?

I am using Dynamodb streams to do some work on records as they are added or modified to my table. I am also using Dynamoose models in my application.
The Dynamodb stream event passes an event object to my node.js lambda handler that includes the objects record.dynamoDb.NewImage and record.dynamoDb.OldImage. However, these objects are in DynamoDB's AttributeValue format including all of the data types ('S' for string), rather than a normal javascript object. So record.id becomes record.id.S.
Dynamoose models allow you to instantiate a model from an object, like so: new Model(object). However, it expects that argument to be a normal object.
I know that Dynamoose has a dynamodb parser, I think its Schema.prototype.dynamodbparse(). However, that doesn't work as expected.
import { DYNAMODB_EVENT } from '../../constant';
import _get from 'lodash/get';
import { Entry } from '../../model/entry';
import { applyEntry } from './applyEntry';
async function entryStream(event) {
await Promise.all(
event.Records.map(async record => {
// If this record is being deleted, do nothing
if (DYNAMODB_EVENT.Remove === record.eventName) {
return;
}
// What I've tried:
let entry = new Entry(record.dynamodb.NewImage);
// What I wish I could do
entry = new Entry(Entry.schema.dynamodbparse(record.dynamodb.newImage));
await applyEntry(entry);
})
);
}
export const handler = entryStream;
So is there a way to instantiate a Dynamoose model from DynamoDB's AttributeValue format? Has anyone else done this?
The alternative, is that I simply extract the key from the record, and then make a trip to the database using Model.get({ id: idFromEvent }); But I think that would be inefficient, since the record was just handed to me from the stream.
I solved it by using AWS.DynamoDB.Converter.unmarshall to parse the object before passing to Dynamoose.
import { DYNAMODB_EVENT } from '../../constant';
import _get from 'lodash/get';
import { Entry } from '../../model/entry';
import { applyEntry } from './applyEntry';
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/Converter.html#unmarshall-property
var AWS = require('aws-sdk');
var parseDynamo = AWS.DynamoDB.Converter.unmarshall;
async function entryStream(event) {
await Promise.all(
event.Records.map(async record => {
// If this record is being deleted, do nothing
if (DYNAMODB_EVENT.Remove === record.eventName) {
return;
}
entry = new Entry(parseDynamo(record.dynamodb.newImage));
await applyEntry(entry);
})
);
}
export const handler = entryStream;

AutoIncrement of Multiple columns in indexeddb

Does any one know - how we can specify autoincrement for two columns in indexeddb.
I know - we can specify autoincremnt for one column while creating table like this -
var objectStore = thisDb.createObjectStore("note", { keyPath: "id", autoIncrement:true });
but not able to find how we can do the same for multiple columns. Also as far as i know - we cant get the value of autoincrement. The value will be autoincremented & added when we will insert the data. So if i can get the autoincrement value somehow, that would the solution too.
You cannot create two auto-incremented properties in a store. That feature is only available for the property defined as the key path.
You can easily get the auto-incremented value. The value is provided as the result of the put or add request that inserted a new object.
For example:
function addThing(db, thing) {
return new Promise((resolve, reject) => {
let id = undefined;
const transaction = db.transaction('things', 'readwrite');
const store = transaction.objectStore('things');
// wait to resolve the promise until the transaction is completed
// so that we do not prematurely pretend the operation succeeded. resolve
// to the value of the new id
transaction.oncomplete = event => resolve(id);
transaction.onerror = event => reject(event.target.error);
// store.add also works here
const request = store.put(thing);
// listen for the add event and grab the value of the new id
// that indexedDB generated and store it in the id variable
request.onsuccess = event => id = event.target.result;
});
}
async function doSomething() {
const something = {bar: 'baz'};
const db = await open(...);
const id = await addThing(db, something);
db.close();
something.id = id;
console.log(something);
}

Firebase check if database exists

I have a firebase database of form: https://imgur.com/ar8A3DN
I would like two functions:
1. refExists, check if any child exists in database. So that
refExists('datasets') = true
refExists('foo') = false
createChild that creates a new child.
My firebase database instance is declared via:
const accountKeyPath = path.join(__dirname, 'path/to/serviceAccountKey.json')
const accountKey = require(accountKeyPath);
const firebaseAdmin = admin.initializeApp(accountKey);
const dbRef = firebaseAdmin.database().ref('datasets');
The interesting thing is that dbRef and this code which should return an error:
const badRef = firebaseAdmin.database().ref('foo')
both output the same thing. So it's unclear how to check the existence of foo when ref('datasets') and ref('foo') behave the same way.
The way to check whether an element exists is by trying to retrieve a snapshot of it - if the snapshot returns null then the element does not exist.
Adding elements is as simple as calling set on the desired element path with a data object.
function refExists(path) {
firebaseAdmin.database().child(path).once('value', (snap) => {
if (snap.val() !== null) {
console.log('ref exists');
}
});
}
function addRef(newPath, data) {
firebaseAdmin.database().child(newPath).set(data);
}

Resources