Closed StephanWalters closed 8 months ago
Hi @StephanWalters! Thanks for using passkit-generator!
addBuffer
, as the name says, accepts a NodeJS Buffer
, which extends (or shares properties with) UInt8Array
.
An ArrayBuffer
is just a raw data representation, without a specific meaning (e.g. Big Endian or Little Endian notation or byte size for a single cell). To be read, it requires a View.
UInt8Array
is one of the TypedArrays belonging to the Web standard that compose and, as it is a TypedArray, it can act as a View for your ArrayBuffer
.
An ArrayBuffer
doesn't own a property length
, but instead a byteLength
(I think the reason is exactly this one, to avoid confusion), so it stops right here:
So, my guess here is that it should work if you do something like:
const productImageAB = await nodeFetch("https image URL").then(res => res.arrayBuffer());
const productImage = Buffer.from(productImageAB);
newPass.addBuffer("name", productImage);
Could you please try and let me know?
Thank you!
@alexandercerutti thank you for the quick reply!
I tried but am still receiving no error and no image in the pass. I am also seeing this warning. But i am also getting a weird user experience. Im currently testing my implementation firing a firebase url request that returns the pass. However, changing to use Buffer.from() returns a 200, but i don't get a pass. Instead Safari (on iPhone) just reloads whatever webpage was on screen prior to me executing my function.
Argument type Buffer is not assignable to parameter type Buffer.
I am not sure if this makes a difference, but i am also using PKPass.from (with a small pass.json) instead of the constructor PKPass(). I am doing this because i ran out of memory with my cloud function do using multiple buffers for the first dictionary used in PKPass().
const sellerImage = await nodeFetch(sellerData.photo);
const productImage = await nodeFetch(productPhoto);
const sellerImageBuffer = await sellerImage.arrayBuffer();
const productImageBuffer = await productImage.arrayBuffer();
const sellerfromBuffer = Buffer.from(sellerImageBuffer);
const productfromBuffer = Buffer.from(productImageBuffer);
logger.debug(`sellerData.photo: ${sellerData.photo}`);
logger.debug(`product photo: ${productPhoto}`);
newPass.addBuffer("thumbnail@1x.png",
sellerfromBuffer);
newPass.addBuffer("thumbnail@2x.png",
sellerfromBuffer);
newPass.addBuffer("background.png",
productfromBuffer);
newPass.addBuffer("background@2x.png",
productfromBuffer);
May I ask you why you're still using node-fetch, when starting from Node 17, fetch
is available globally? I see you are running on Node 18. May I ask you to use it to be sure it is specifically compliant with the standard? I don't think this will solve it, but who knows...
Argument type Buffer is not assignable to parameter type Buffer.
I'm not sure where this happens exactly. Do you have any further details?
I tried but am still receiving no error and no image in the pass. I am also seeing this warning. But i am also getting a weird user experience. Im currently testing my implementation firing a firebase url request that returns the pass. However, changing to use Buffer.from() returns a 200, but i don't get a pass. Instead Safari (on iPhone) just reloads whatever webpage was on screen prior to me executing my function.
That's kind of weird. Do you have perhaps a repro case that I could use to investigate?
@alexandercerutti no particular reason. I'm primary is a front end mobile dev (iOS) and self taught myself javascript/Node.js.
As far as: Argument type Buffer is not assignable to parameter type Buffer.
it seemed to be a type missmatch importing node buffer cleared the warning. const {Buffer} = require("node:buffer");
This is index.js firebase onRequest function. I removed a few strings and replaced with HIDDEN, but this is pretty much my exact function. Removing the newPass.addBuffer() will recreate the pass, but removing it wont. Something else, that i see that's odd is with this code (on desktop) it creates a pkpasses bundle, which is 14.4MB (thats crazy large) without the newPass.addBuffer() it will work on safari web and mobile but the pass is much smaller.
const {onRequest} = require("firebase-functions/v2/https");
REDACTED
The TL;DR: I am passing the orderId as a query parameter to get an order from the database. there is an items array that has a list of item objects (purchases) I am looping through those to create product passes and packing them together and returning as a stream.
Something else, that i see that's odd is with this code (on desktop) it creates a pkpasses bundle, which is 14.4MB (thats crazy large) without the newPass.addBuffer() it will work on safari web and mobile but the pass is much smaller.
It depends on your assets. I do not apply any compression, but I just concatenate the buffers. I made available a "hook" (.getAsRaw()
) to let people apply their compression and serve the compiled pass. I don't know how many pkpass are you zipping inside your .pkpasses
zip file, so 14MB might be reasonable based on the sizes of your assets.
By the way, please note that .pkpasses
that you are trying to output are supported only by Safari (and Mail) and I think only on iPhone; I'm not sure they are supported on Desktop.
About your code, I can suggest you one or two things:
1) Move the reading of the certificates outside the loop. You only need them once.
2) Try to build only one .pkpass
and check if there's anything different.
3) Try following the guide for debugging that I set up in the wiki and check if, when downloading the pass, some weird error pops on. Apple logs and errors for Apple Wallet are not documented at all, so if you find something weird, I please you to report it here, so it can be useful to other developers in the future.
@alexandercerutti i am closing this issue due to human error. I was creating a coupon type pass and the image needed was strip.png. Sorry about that
Don't worry, @StephanWalters! Glad you solved!
It would be awesome if you could leave a 🌟 on the project!
Don't worry, @StephanWalters! Glad you solved!
It would be awesome if you could leave a 🌟 on the project!
just did! thank you!
Running OS
Environment: Firebase Cloud Functions Node.js 18 functions.
Running Node Version 18
Description
When trying to use addBuffer to dynamically add an image to the pass. It doesn't add, but no error is thrown. I am using node-fetch to fetch the image and then converting as an ArrayBuffer.
Expected behavior
Expecting the background image to be added to the pass.
Steps to reproduce
Code:
Were you able to verify it by using (and changing) the examples?
If yes, which changes did you apply?
Other details