I used npm to install the Binance API node. I reach to the following step:
import Binance from 'binance-api-node'
const client = Binance()
// Authenticated client, can make signed calls
const client2 = Binance({
apiKey: 'xxx',
apiSecret: 'xxx',
getTime: xxx, // time generator function, optional, defaults to () => Date.now()
})
client.time().then(time => console.log(time))
Could you please guide me on how to run this part. The node module could be found on https://github.com/Ashlar/binance-api-node
You'll need to create your API key following this doc
2. Once you have your API key and secret key, you store in apiKey and apiSecret respectively.
3. If you do not have an appropriate babel config, you will need to use the basic commonjs requires.
const Binance = require('binance-api-node').default instead of ES6 import
Related
So I am using firebase-admin in Next Js. I used environment variables but can't hide the firebase service account keys because they are not defined in server-side on Next JS. So i had to use NEXT_PUBLIC environment variables. And NEXT_PUBLIC environment variables can be accessed and viewed in client side.
This is my firebase-admin file
const firebase = require("firebase-admin");
const { fireStore, getFirestore } = require("firebase-admin/firestore");
import { adminConfig } from "./serviceAccountKey";
if (!firebase.apps.length) {
firebase.initializeApp({
credential: firebase.credential.cert(adminConfig),
});
}
export const db = getFirestore();
export default firebase;
And this is how my config object looks like.
export const adminConfig = {
type: process.env.NEXT_PUBLIC_FIREBASE_TYPE,
project_id: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
private_key_id: process.env.NEXT_PUBLIC_FIREBASE_PRIVATE_KEY_ID,
private_key: process.env.NEXT_PUBLIC_FIREBASE_PRIVATE_KEY,
client_email: process.env.NEXT_PUBLIC_FIREBASE_CLIENT_EMAIL,
client_id: process.env.NEXT_PUBLIC_FIREBASE_CLIENT_ID,
auth_uri: process.env.NEXT_PUBLIC_FIREBASE_AUTH_URI,
token_uri: process.env.NEXT_PUBLIC_FIREBASE_TOKEN_URI,
auth_provider_x509_cert_url:
process.env.NEXT_PUBLIC_FIREBASE_AUTH_PROVIDER_CERT_URL,
client_x509_cert_url: process.env.NEXT_PUBLIC_FIREBASE_CLIENT_CERT_URL,
};
So How do i hide the config data. Or is it alright even if it is public?
I managed to do this in NextJS some time back (hopefully it's still relevant) - try this:
Store your secrets as environment variables in a .env file.
In your next.config.js load the environment variables in publicRuntimeConfig
publicRuntimeConfig: {
PRIVATE_KEY: process.env.FIREBASE_PRIVATE_KEY_ID,
PRIVATE_KEY_ID: process.env.FIREBASE_PRIVATE_KEY
}
Then in your client side React:
import getConfig from 'next/config';
const {publicRuntimeConfig} = getConfig();
const private_key = publicRuntimeConfig.PRIVATE_KEY
const private_key_id = publicRuntimeConfig.PRIVATE_KEY_ID
EDIT: Actually, now that I think about it, I used this method for things that didnt require absolute security like API_URIs.
Secrets stored/accessed like this will still be exposed to inspection in the browser.
For anything that requires securely storing secrets, definitely perform them on server-side.
I want to make a cloud function that uses 'firebase' module (not a 'firebase-functions')
And when I'm using or even only import it, npm throws an error:
Error: Error parsing triggers: Failed to load gRPC binary module because it was not installed for the current system
Expected directory: node-v64-darwin-x64-unknown
Found: [node-v79-darwin-x64-unknown]
This problem can often be fixed by running "npm rebuild" on the current system
Original error: Cannot find module '/Users/rame/functions/node_modules/grpc/src/node/extension_binary/node-v64-darwin-x64-unknown/grpc_node.node'
1) If you want to compile the package/file into executable, please pay attention to compilation warnings and specify a literal in 'require' call. 2) If you don't want to compile the package/file into executable and want to 'require' it from filesystem (likely plugin), specify an absolute path in 'require' call using process.cwd() or process.execPath
here's my code on Type script:
import * as functions from 'firebase-functions';
import admin = require('firebase-admin');
//the cause of an error
import * as firebase from 'firebase';
admin.initializeApp()
export const getProfilePicture = functions.https.onRequest((request, response) => {
//also there
const uid = firebase.auth().currentUser?.getIdToken
const promise = admin.storage().bucket().file('usersPfp/' + uid).getSignedUrl({
action: 'read',
expires: '03-09.2441'
})
const p2 = promise.then(GetSignedUrlResponse => {
const data = GetSignedUrlResponse[0]
return response.send({"data": data})
})
p2.catch(error =>{
console.log(error)
return response.status(500).send({"error": error})
})
})
How to fix that?
What you're doing isn't supported. The Firebase Authentication JavaScript client library isn't supported for use in backend environments like Cloud Functions.
The idea of a current user:
firebase.auth().currentUser
only makes sense in the client app where the user is signed in. It's not something that's known on the backend.
What you can do instead is send the user's ID token from your client to your function, the use the Admin SDK to verify it, then perform some actions on the user's behalf.
I am trying to fetch a value from my collection using the createdAt property, which is a timestamp.
This is roughly what my query looks like:
function getDataFromYesterdayToNow (db){
const now = new Date()
const yesterday = new Date(now.setDate(now.getDate() - 1))
yesterday.setHours(0, 0, 0, 0)
const { Timestamp } = firebase.firestore
return db
.collection('myData')
.where('createdAt', '>=', Timestamp.fromDate(yesterday))
.where('createdAt', '<=', Timestamp.fromDate(now))
.get()
}
However, when I run this, I get the following error:
error was 'FirebaseError: [code=invalid-argument]: Function Query.where() called with invalid data. Unsupported field value: a custom Timestamp object'. Stacktrace was 'FirebaseError: Function Query.where() called with invalid data. Unsupported field value: a custom Timestamp object
I am super confused, I have always fetched using Timestamp objects in other collections, and it does not work if I try to just use the date object. Have I forgotten something?
Edit: as requested, here is an example of what my doc looks like:
{
name: "My Data Name", // (string)
createdAt: November 9, 2018 at 8:40:45 PM // (Timestamp)
}
I had the same issue. There are two things you need to check.
1. Am I using the right SDK?
Did you know there are two different firebase SDK you can use? One is a client SDK (firebase-js-sdk a.k.a. firebase package) and the other one is a firebase server SDK (nodejs-firestore .a.k.a. #google-cloud/firebase package). These two libraries have its own implementation on firestore.Timestamp class and THEY ARE NOT COMPATIBLE.
Some of the other NPM packages dependencies as follow:
"#firebase/firestore" (*)
-> "firebase" (client SDK which imports all #firebase/* except #firebase/testing)
-> "#angular/fire" (and other client libraries with firebase binding)
-> "#firebase/testing" (mocking Firestore client)
"#google-cloud/firebase" (*) (server SDK)
-> "firebase-admin"
-> "firebase-functions-test"
Where (*) denotes the location of firestore.Timestamp definition.
In short, you should use corresponding Timestamp.
Case 1. Use a client SDK only
import { firestore, initializeApp } from 'firebase';
import { config } from './my-firebase-config';
const app = initializeApp(config);
app.firestore().collection('users')
.where('createdAt', '<=', firestore.Timestamp.fromDate(new Date()))
.get();
Case 2. Use a server SDK only
import { firestore, initializeApp } from 'firebase-admin';
const app = initializeApp();
app.firestore().collection('users')
.where('createdAt', '<=', firestore.Timestamp.fromDate(new Date()))
.get();
Case 3. Mixing SDKs
Sometimes you need to use client SDK (specifically, #firebase/testing) when you're testing code that are run on server (e.g. firebase functions.)
// server.ts
import { firestore, initializeApp } from 'firebase-admin';
const app = initializeApp();
app.firestore().collection('users')
.where('createdAt', '<=', fs.Timestamp.fromDate(new Date()))
.get();
// server.test.ts
import { firestore } from 'firebase';
import { initializeAdminApp } from '#firebase/testing';
// Replace server sdk with client sdk
jest.mock('firebase-admin', () => ({
firestore,
initializeApp: () => initializeAdminApp()
}));
2. Am I using the right version?
If you're using the correct SDK, the next thing to check is whether you're using the same version of Timestamp implementation. If you're using Client SDK for example, then you should check your package-lock.json whether it has a unique version of firebase.
For my case, I installed #firebase/testing and firebase in a different time, and due to the difference firebase version dependency from #firebase/testing, I had two different firebase packages installed at the same time. You can update an old package to fix this.
I'm uploading an image file from React Native to AWS Lambda (Node 10.x) and want to verify the hash of the file I've sent matches the file received. To do this I'm using hashing in React Native and again in Lambda, but the hashes never match. Here are the relevant bits of code I've tried.
React Native
import RNFS from "react-native-fs";
const contentChecksum = await RNFS.hash(post.contentUrl, "md5");
Lambda (Node)
import AWS from "aws-sdk";
const crypto = require("crypto");
const s3 = new AWS.S3();
const data = await s3
.getObject({
Bucket: file.bucket,
Key: file.key
})
.promise();
const contentChecksum = crypto
.createHash("md5")
.update(data.Body)
.digest("hex");
These checksums never match. I've tried using base64 encoding in Node (data.Body.toString("base64")) and also sha256. What is the trick to calculating the checksum so they match in React Native and Node?
Edit: Here are the results from a recent test.
post.contentUrl: file:///Users/xxxxxxx/Library/Developer/CoreSimulator/Devices/2F2F4FD3-574E-40D7-BE6B-7080E926E70A/data/Containers/Data/Application/65A3FF67-98B2-444D-B75D-3717C1274FBC/Library/Caches/Camera/FDCD8F90-D24F-4E64-851A-96AB388C4B59.jpg
(the file is local on an iPhone)
contentChecksum from React Native: 48aa5cdb30f01719a2b12d481dc22f04
contentChecksum from Node (Lambda): 7b30b61a55d2c39707082293c625fc10
data.Body is a Buffer.
I also note that the eTag attribute on the S3 object matches the md5 checksum I'm calculating in Node. Since eTag is usually the md5 hash of the file, this tells me that I'm likely calculating the hash incorrectly in React Native, but I'm not sure how. I'm using the hash function from the react-native-fs package.
You can use the same code on React and AWS Lambda, that is Node.js.
So in your React.js application you could use the following code:
import * as React from 'react';
import crypto from 'crypto';
var key = 'YOUR_KEY';
export default class Test extends React.Component {
render() {
var hash = crypto.createHash('md5').update(key).digest('hex');
return (
<div>
{hash}
</div>
)
}
}
And the variable hash have to contains the same value you get on AWS.
In order to run you have to install the crypto library:
npm i --save react-native-crypto
Change the variable YOUR_KEY, then run the application:
npm start
And in the browser you should get:
4b751fef5e9660e3943173fd3e6c4224
You can use the crypto module.
To get a list of all available hash algorithms, you can use crypto.getHashes().
Here is a Nodejs example:
var crypto = require('crypto')
crypto.getHashes() // [ 'dsa', 'dsa-sha', ..., 'md5', ... ]
Here is a helper method for generating checksum value from string input:
var crypto = require('crypto')
function checksum(str, algorithm, encoding) {
return crypto
.createHash(algorithm || 'md5')
.update(str, 'utf8')
.digest(encoding || 'hex')
}
checksum('This is my test text');
checksum('This is my test text', 'sha1');
Cloud Functions - Cloud Firestore error: can't get serverTimestamp
const admin = require('firebase-admin');
exports.userlog = functions.firestore
.document('user/{userId}')
.onUpdate((change, context) =>
{
const db = admin.firestore();
//var timestamp = db.FieldValue.serverTimestamp();
var timestamp = db.ServerValue.TIMESTAMP;
...
return db.collection('userlog').add(
{
userId : previousValue.userId,
...
timestamp: timestamp
}).then(ref =>
{
return console.log('Added document with ID: ', ref.id);
});
});
I got two errors separately:
TypeError: Cannot read property 'serverTimestamp' of undefined
TypeError: Cannot read property 'TIMESTAMP' of undefined
The correct syntax is:
firebase.firestore.FieldValue.serverTimestamp()
Note the lack of parenthesis (()) after firestore: this is a static variable, not an instance variable/member field.
// Imports: Dependencies
const admin = require('firebase-admin');
// Correct Syntax (If You Don't Want To Import Firestore)
created_at: admin.firestore.FieldValue.serverTimestamp(),
since #FrankvanPuffelen's edit queue is full with missing imports, documentation, etc I'll post an update on his solution
include from (web version 8):
const firebase = require('firebase-admin');
or use more recent (web version 9):
import {FieldValue} from "firebase/firestore";
The correct syntax is:
firebase.firestore.FieldValue.serverTimestamp()
Note the lack of parenthesis (()) after firestore: this is a static variable, not an instance variable/member field.
See Firebase example for more info
I was using the correct syntax as per the upvoted answer(s), but still go this error. It turns out it had something to do with my version of the firebase CLI being off-sync with versions of the firebase-admin package (I'm not sure how it happened in the first place, but I noticed form my source tracking tool that the package.json and lock files had been updated).
Solved the problem by deleting all changes I had made on my package.json & lock files and re-installed the CLI:
npm i -g firebase-tools