Trouble with uploading files to firebase storage - javascript

I'm learning about puppeteer and firebase at the moment. What I am trying to do is create a pdf of a web page and upload to firebase storage. This is my code.
const puppeteer = require('puppeteer');
const fs = require('fs').promises;
const firebase = require('firebase');
require("firebase/storage");
const url = process.argv[2];
if (!url) {
throw "Please provide URL as a first argument";
}
var firebaseConfig = {
#Firebase Config Goes here
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
#Function to generate PDF file
async function run () {
const browser = await puppeteer.launch();
const page = await browser.newPage();
//await page.goto(url);
await page.goto(url, {waitUntil: 'domcontentloaded', timeout: 60000} );
//await page.pdf({ path: 'api.pdf', format: 'A4' })
const myPdf = await page.pdf();
await browser.close()
return myPdf;
}
const myOutput = run();
#Upload to Firebase based on the instruction here https://firebase.google.com/docs/storage/web/upload-files
var storageRef = firebase.storage().ref();
// Create a reference to 'mountains.jpg'
storageRef.child(myOutput).put(myOutput)
However, I'm running into this error when executing my code
$ node screenshot.js https://en.wikipedia.org/wiki/Aung_San_Suu_Kyi
C:\Users\ppham\NucampFolder\Test\node_modules\#firebase\storage\dist\index.cjs.js:1040
.split('/')
^
TypeError: childPath.split is not a function
at child (\Test\node_modules\#firebase\storage\dist\index.cjs.js:1040:10)
at getChild (\Test\node_modules\#firebase\storage\dist\index.cjs.js:2610:19)
at ReferenceCompat.child (Test\node_modules\#firebase\storage\dist\index.cjs.js:2833:25)
at Object.<anonymous> (C:\Users\ppham\NucampFolder\Test\screenshot.js:55:12)
at Module._compile (internal/modules/cjs/loader.js:936:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:947:10)
at Module.load (internal/modules/cjs/loader.js:790:32)
at Function.Module._load (internal/modules/cjs/loader.js:703:12)
at Function.Module.runMain (internal/modules/cjs/loader.js:999:10)
at internal/main/run_main_module.js:17:11
It is saying that childPath.split is not a function. I'm pretty confused at this since I've already installed all the firebase packages. I've been searching for this error for a while but no luck so far. Anyone knows how to resolve this issue?
===============================================================================
Edit #1: As Frank pointed out below, I have to change storageRef.child(myOutput).put(myOutput) to something like storageRef.child("filename.pdf").put(myOutput). It runs but I'm running into this error afterwards.
$ node screenshot.js https://google.com
Promise { <pending> }
(node:20636) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'byteLength' of undefined
at C:\Users\ppham\NucampFolder\Test\node_modules\#firebase\storage\dist\index.cjs.js:833:40
at Array.forEach (<anonymous>)
at Function.FbsBlob.getBlob (C:\Users\ppham\NucampFolder\Test\node_modules\#firebase\storage\dist\index.cjs.js:832:25)
at multipartUpload (C:\Users\ppham\NucampFolder\Test\node_modules\#firebase\storage\dist\index.cjs.js:1519:24)
at C:\Users\ppham\NucampFolder\Test\node_modules\#firebase\storage\dist\index.cjs.js:2003:31
at C:\Users\ppham\NucampFolder\Test\node_modules\#firebase\storage\dist\index.cjs.js:1900:21
at processTicksAndRejections (internal/process/task_queues.js:85:5)
(node:20636) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:20636) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
This looks to imply that myOutput doesn't contain anything. I thought that I have return the pdf in the run function and it will be passed over to the upload function? I've been reading the Puppeteer documentation and couldn't find any reason why this wouldn't work. Anyone knows why this is not valid?

The error message is saying that the value you're passing to child() is not a string.
Since you're calling:
storageRef.child(myOutput).put(myOutput)
That kind'of makes sense. My guess is that you want to pass a file name into child(), like:
storageRef.child("filename.pdf").put(myOutput)

Related

No Node Found For Selector - Puppeteer

So today I am using a node framework called puppeteer which basically controls all aspects of your browser. I am trying to make a checkout bot but I am getting an error while trying to navigate to the other page. I am using Nike for this example. Here is the error shown:
^
Error: No node found for selector: #f25e2320-d66d-48f3-88b3-cd92f4c5c1cd
at exports.assert (C:\Users\Shushan\Desktop\firebaseSampleTest\node_modules\puppeteer\lib\cjs\puppeteer\common\assert.js:26:15)
at DOMWorld.type (C:\Users\Shushan\Desktop\firebaseSampleTest\node_modules\puppeteer\lib\cjs\puppeteer\common\DOMWorld.js:306:21)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async C:\Users\Shushan\Desktop\firebaseSampleTest\index.js:88:29
Node.js v18.3.0
PS C:\Users\Shushan\Desktop\firebaseSampleTest> ^C
PS C:\Users\Shushan\Desktop\firebaseSampleTest> node .
I am ready!
(node:40328) DeprecationWarning: The message event is deprecated. Use messageCreate instead
(Use `node --trace-deprecation ...` to show where the warning was created)
(node:40328) DeprecationWarning: Passing strings for MessageEmbed#setAuthor is deprecated. Pass a sole object instead.
C:\Users\Shushan\Desktop\firebaseSampleTest\node_modules\puppeteer\lib\cjs\puppeteer\common\assert.js:26
throw new Error(message);
^
Error: No node found for selector: #f25e2320-d66d-48f3-88b3-cd92f4c5c1cd
at exports.assert (C:\Users\Shushan\Desktop\firebaseSampleTest\node_modules\puppeteer\lib\cjs\puppeteer\common\assert.js:26:15)
at DOMWorld.type (C:\Users\Shushan\Desktop\firebaseSampleTest\node_modules\puppeteer\lib\cjs\puppeteer\common\DOMWorld.js:306:21)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async C:\Users\Shushan\Desktop\firebaseSampleTest\index.js:88:29
Node.js v18.3.0
PS C:\Users\Shushan\Desktop\firebaseSampleTest>
When I am clicking on the continue to cart button in Nike, it is rerouting me to the login page. The input with the ID #f25e2320-d66d-48f3-88b3-cd92f4c5c1cd is appearantly not showing in the page, but it clearly is. My code files are below:
index.js
const url = 'https://www.nike.com/t/air-max-270-mens-shoes-KkLcGR/DQ7642-100';
(async () => {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto(`${args}`);
await page.click('.wishlist-btn');
page.setDefaultNavigationTimeout( 90000 );
await page.type('#f25e2320-d66d-48f3-88b3-cd92f4c5c1cd', 'Hello World');
})();
Again like I said before, when I click the button on the URL https://www.nike.com/t/air-max-270-mens-shoes-KkLcGR/DQ7642-100, it reroutes the browser to the login page but there Puppeteer is showing me an error that the node is not found. Can someone please help me with this error? Thanks.

IPFSAccessController.save ERROR: Error: Deprecated, use .toString()

i'm only trying to launch the exemple of the app kit OrbitDB which is :
import OrbitDB from "orbit-db";
import IPFS from "ipfs";
async function main () {
// Create IPFS instance
const ipfsOptions = { repo : './ipfs', }
const ipfs = await IPFS.create(ipfsOptions)
// Create OrbitDB instance
const orbitdb = await OrbitDB.createInstance(ipfs)
// Create database instance
const db = await orbitdb.keyvalue('ipfs_db')
}
main()
you can find it here : https://github.com/dappkit/aviondb#using-nodejs
but the problem is when i launch it, i got these errors :
Swarm listening on /ip4/127.0.0.1/tcp/4002/p2p/12D3KooWM7D9NdMhtxyiWiKH4XVpuZW5oDu9MbWxFmEzLsG9UynM
Swarm listening on /ip4/192.168.1.53/tcp/4002/p2p/12D3KooWM7D9NdMhtxyiWiKH4XVpuZW5oDu9MbWxFmEzLsG9UynM
Swarm listening on /ip4/127.0.0.1/tcp/4003/ws/p2p/12D3KooWM7D9NdMhtxyiWiKH4XVpuZW5oDu9MbWxFmEzLsG9UynM
IPFSAccessController.save ERROR: Error: Deprecated, use .toString()
at CID.get toBaseEncodedString [as toBaseEncodedString] (/home/zar/Etna4/SmartContract/db_ipfs/node_modules/multiformats/cjs/src/cid.js:94:11)
at Object.writeCbor [as write] (/home/zar/Etna4/SmartContract/db_ipfs/node_modules/aviondb/node_modules/orbit-db-access-controllers/node_modules/orbit-db-io/index.js:62:14)
at async IPFSAccessController.save (/home/zar/Etna4/SmartContract/db_ipfs/node_modules/aviondb/node_modules/orbit-db-access-controllers/src/ipfs-access-controller.js:46:13)
at async Function.create (/home/zar/Etna4/SmartContract/db_ipfs/node_modules/aviondb/node_modules/orbit-db-access-controllers/src/access-controllers.js:68:20)
at async OrbitDB._determineAddress (/home/zar/Etna4/SmartContract/db_ipfs/node_modules/aviondb/node_modules/orbit-db/src/OrbitDB.js:331:37)
(node:8397) UnhandledPromiseRejectionWarning: Error: `undefined` is not supported by the IPLD Data Model and cannot be encoded
at undefinedEncoder (/home/zar/Etna4/SmartContract/db_ipfs/node_modules/#ipld/dag-cbor/cjs/index.js:47:9)
at objectToTokens (/home/zar/Etna4/SmartContract/db_ipfs/node_modules/cborg/cjs/lib/encode.js:175:20)
at Object (/home/zar/Etna4/SmartContract/db_ipfs/node_modules/cborg/cjs/lib/encode.js:149:9)
at objectToTokens (/home/zar/Etna4/SmartContract/db_ipfs/node_modules/cborg/cjs/lib/encode.js:184:10)
at Object (/home/zar/Etna4/SmartContract/db_ipfs/node_modules/cborg/cjs/lib/encode.js:149:9)
at objectToTokens (/home/zar/Etna4/SmartContract/db_ipfs/node_modules/cborg/cjs/lib/encode.js:184:10)
at encodeCustom (/home/zar/Etna4/SmartContract/db_ipfs/node_modules/cborg/cjs/lib/encode.js:214:18)
at Object.encode (/home/zar/Etna4/SmartContract/db_ipfs/node_modules/cborg/cjs/lib/encode.js:236:10)
at Object.encode (/home/zar/Etna4/SmartContract/db_ipfs/node_modules/#ipld/dag-cbor/cjs/index.js:85:41)
at put (/home/zar/Etna4/SmartContract/db_ipfs/node_modules/ipfs-core/src/components/dag/put.js:35:25)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:8397) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:8397) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
i seriously don't know what to do, i tried to clear the cache, to delete node_modules and package-lock.json, and do a npm install, but nothing changed, i got the same error, do you have any idea to fix this ?
This error clearly points to an incompatibility between IPFS and OrbitDB.
The latest version of js-ipfs that OrbitDB v0.26.1 supports is 0.55.4.
You should change the ipfs (or ipfs-core) version in your package.json to ^0.55.4.
Note: The upcoming OrbitDB v0.27, will support the latest IPFS version.

Logging messages from one channel

I've tried several times to work this and I don't understand the error, I am receiving but I'll explain what I'm trying to do: Basically I want to log the messages from one channel and paste those messages onto a different channel. Here is the code I have so far;
client.on(`message`, message => {
if (message.author.bot) return; // If the message is by a bot return.
if (!message.guild) return; // If the message isn't in a guild return.
if (message.guild) {
const msgLog = `[MESSAGE] [${message.guild.name}] [#${message.channel.name}] ${message.author.username}#${message.author.discriminator}: ${message.content}\n` // You can change this to whatever you want.
client.channels.get(`814685640088223795`).send(msgLog); // Replace CHANNEL ID with the channel ID you want the logs to go to.
return;
}
})
The error I am receiving goes as follows:
(node:17260) UnhandledPromiseRejectionWarning: ReferenceError: client is not defined
at Object.<anonymous> (D:\stuff\S1 Discord Bot\s1-bot\src\events\message\message.js:1:1)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Module.require (internal/modules/cjs/loader.js:952:19)
at require (internal/modules/cjs/helpers.js:88:18)
at registerEvents (D:\stuff\S1 Discord Bot\s1-bot\src\utils\registry.js:33:21)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:17260) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:17260) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Thanks
You are missing this from your index file:
const Discord = require("discord.js");
//under const Discord etc
const client = new Discord.Client();
If you are trying to only allow guildMessages, you do it like this:
if (message.channel.type === "dm") return; //dont react to dms
Finally, to send a message to a channel by id:
message.guild.channels.cache.get('814685640088223795').send(msglog); //using 'cache' since v12 uses managers
You seem to be missing two important lines of code:
const Discord = require('discord.js');
const client = new Discord.Client();
Appending these two lines from the discord.js documentation in the beginning of your index.js file should make it work.

Javascript is losing a backtrace in the catch block

The following code sample:
async function expectResolutionErrorCode(object) {
try {
await Promise.resolve(1);
object.f1() // caught error
} catch (error) {
object.f2() // uncaught error
}
}
expectResolutionErrorCode(undefined).catch(err => console.log(err));
Produces the following backtrace when run using node v14:
$ node test.ts
TypeError: Cannot read property 'f2' of undefined
at expectResolutionErrorCode (/Users/bogdan/makabu/unstoppable/resolution/test.ts:6:12)
If I comment out the await statement at line 3 from the sample, the backtrace is complete:
TypeError: Cannot read property 'f2' of undefined
at expectResolutionErrorCode (/Users/bogdan/makabu/unstoppable/resolution/test.ts:6:12)
at Object.<anonymous> (/Users/bogdan/makabu/unstoppable/resolution/test.ts:10:1)
at Module._compile (internal/modules/cjs/loader.js:1201:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1221:10)
at Module.load (internal/modules/cjs/loader.js:1050:32)
at Function.Module._load (internal/modules/cjs/loader.js:938:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
So the await statement clearly causes node to lose some part of the backtrace.
Why does it behave like that?
Is there any workaround to maintain the backtrace while still using await statements inside try catch?
I tested this behavior in Chrome and Safari and the stacktrace is lost in almost the same way: https://jsfiddle.net/61kdv8fx/
It's because the stack has unwound. Remember that await is syntactic sugar for hooking the settlement of a promise. So when you reach the await in your code, the function returns. Later, when the code continues because the promise was settled, the stack is shallow because promise reactions are called directly.
JavaScript tool makers are very aware of this and working on async call stacks to address it.
However, I should note that when I try to replicate what you're seeing on Node v14, I don't see it, because V8 already has async call stacks. Example:
async function example() {
try {
await Promise.resolve(1); // Could just be `await 1;`, but I wanted to match the question
throw new Error("boom1");
} catch (e) {
throw new Error("boom2");
}
}
async function a() {
await b();
}
async function b() {
await c()
}
async function c() {
await example();
}
a();
When I run it:
$ node example.js
(node:5342) UnhandledPromiseRejectionWarning: Error: boom2
at example (/path/to/example.js:6:15)
at async c (/path/to/example.js:19:5)
at async b (/path/to/example.js:15:5)
at async a (/path/to/example.js:11:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:5342) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:5342) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I get the same sort of output on modern versions of Chrome and other browsers using a recent V8. But Firefox v78 still loses the context; I'm sure the SpiderMonkey team are working on it.

How to take screenshots for multiple pages automatically using Puppeteer

I have a list of URLs in the text file. I want to get the screenshot for each page automatically by reading each URL form the text file using Puppeteer.
const puppeteer = require('puppeteer');
async function doScreenCapture(url, site_name) {
let browser = await puppeteer.launch({ headless: false });
let page = await browser.newPage();
await page.goto(url);
await page.setViewport({width: 1382, height: 717})
await page.waitFor(1000);
console.log('do screen capture running');
await page.screenshot({ path:`${site_name}.png`, fullPage: true });
await page.close();
await browser.close();
}
async function run() {
console.log('running');
var fs = require("fs");
var text = fs.readFileSync("linksList.txt").toString().split("\n");
for (var i = 0; i < text.length; ++i) {
doScreenCapture(text[i], "image"+i)
console.log("image"+i+" completed");
await page.waitFor(5000);
}
}
run();
This is the error I got while running the code
(node:77868) UnhandledPromiseRejectionWarning: ReferenceError: page is not defined
at run
at Object.
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Function.Module.runMain (module.js:694:10)
at startup (bootstrap_node.js:204:16)
at bootstrap_node.js:625:3
(node:77868) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:77868) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
do screen capture running.
I see two issues here:
page does not exist in the "for" loop, only in the "run" function and that gives you the exception. You can move waiting to the function
"doScreenCapture" is an async function and you should use await doScreenCapture in order for pages to be open in succession, not at once.

Categories