# Firebase example

This is a sample project for showing passkit-generator working on a Firebase Cloud Function.

Cloud Functions are Google **a paid service** that run your code like a unit. They take some files in input and output something (in this case the compiled Apple Wallet Pass).

Please note that this example offers just one endpoint example.

## Setting up

Once moved to the `firebase` folder, install all the dependencies through `npm install`.

`firebase-tools` (which are suggested to get installed globally) are installed locally too. To access them, prefix `firebase` command with `npx`, just like in `package.json`.

```sh
$ npx firebase <command>
```

---

Proceed creating your cloud function on firebase portal like shown in [Firebase official documentation](https://firebase.google.com/docs/functions/get-started?hl=en&gen=2nd), step 1. In order to run this example, you don't need to follow the other steps.

Login with your code on firebase. You'll be redirected on a web page to complete login.

```sh
$ npx firebase login
```

You **don't need** to run `firebase init` as the project is already initialized.

Pick your project name and put it inside `.firebaserc` at `project.default`.

Remember: once you setup login, your credentials and used functions will be stored inside in your user root path. On MacOS it is `~/.config/configstore/firebase-tools.json`. You might want to delete it to clear the cache of functions. Deleting it will log you out.

### Setting up the storage

Go to "Storage" on the web page. You'll be provided with an URI that starts by `gs://`.
Take the part right after the protocol and put it in the file `src/startData.json`, at the key `FIREBASE_BUCKET_ADDR`.

![](data:image/png;base64,[encoded data, 46448 characters])

Create a new folder `logos` (like in the screenshot) and upload in there one of the model logo files (called `logo.png`).

### Secrets and certificates

In order to show the example, you'll have to set your certificates data in the `.env` file, which will get deployed along with the Firebase. In production, it is suggested to have either different `.env` files or set these data as secrets.

Open `.env` file and fill the fields. Please remember your should put in there the contents and not the paths.

### Running locally

To run the firebase cloud function emulator, use this command:

```sh
$ npm run serve
```

You will be provided with your local function URL, you can ping (POST Request) with a body like the following one. Keep reading for the parameter reference.

```json
{
	"passModel": "exampleBooking",
	"serialNumber": "unnannasyg1341",
	"transitType": "PKTransitTypeAir",
	"textColor": "rgb(255,255,255)",
	"backgroundColor": "rgb(10,10,10)",
	"labelColor": "rgb(255,255,255)",
	"logoFile": "logo.png",
	"header": [
		{
			"label": "When",
			"value": "10/10/2023"
		}
	],
	"primary": [
		{
			"label": "Napoli Capodichino",
			"value": "NAP"
		},
		{
			"label": "Amsterdam Schiphol",
			"value": "AMS"
		}
	]
}
```

### Deployment

In order to deploy your function, run

```sh
$ npm run deploy
```

While deploying you might/will incur into several error.
While CLI doesn't provide you with very much details, it will create a file in `functions/firebase-debug.log` which will provide very much details on what gone wrong.

For some errors, you might want to try again to deploy without changing anything after a while: it might happen things are still getting created on the backend and not everything is yet synchronized on the backend.

During creation test, some errors came up that didn't came up later, even with a clean situation. If you incur in any problem with this example, please open an issue on passkit-generator repo.

#### Notes on deployed files

Within this examples, models folder are set to be deployed with your function files (see `firebase.json`, `predeploy` and `postdeploy` scripts).
This inherently brings to a higher upload memory and higher deploy times. It might, also, bring to higher cold-startup times.

You might want to consider other options for uploading your models or, perhaps, you might want to use a Buffer Model. If you choose to use Firebase Storage, please remember that it has a free bandwith quota, after which your are going to pay for calls. It is all a trade-off.

## Parameters reference

Function accept an `application/json` body. These are the supported parameters:

| Name                 |                   Type                    | Required | Description                                                                                                          |
| -------------------- | :---------------------------------------: | :------: | -------------------------------------------------------------------------------------------------------------------- |
| passModel            |                 `string`                  |   YES    | Name of the model. Must be one of the `examples/models` folder. `.pass` extension is optional                        |
| serialNumber         |                 `string`                  |   YES    | Serial number of the pass. Required for generating a valid and unique pass                                           |
| logoText             |                 `string`                  |    NO    |                                                                                                                      |
| textColor            |                 `string`                  |   YES    | The `foregroundColor` of `pass.json`                                                                                 |
| backgroundColor      |                 `string`                  |   YES    | The `backgroundColor` of `pass.json`                                                                                 |
| labelColor           |                 `string`                  |   YES    | The `labelColor` of `pass.json`                                                                                      |
| relevantDate         |                 `string`                  |    NO    |                                                                                                                      |
| expiryDate           |                 `string`                  |    NO    |                                                                                                                      |
| relevantLocationLat  |                 `number`                  |    NO    | A latitude to be set on `setLocations`. Must be passed along with `relevandLocationLong`.                            |
| relevantLocationLong |                 `number`                  |    NO    | A longitude to be set on `setLocations`. Must be passed along with `relevantLocationLat`.                            |
| header               | `Array<{ value: string; label: string }>` |    NO    | A set of fields to be shown in the header fields of the pass                                                         |
| primary              | `Array<{ value: string; label: string }>` |    NO    | A set of fields to be shown in the primary fields of the pass                                                        |
| secondary            | `Array<{ value: string; label: string }>` |    NO    | A set of fields to be shown in the secondary fields of the pass                                                      |
| auxiliary            | `Array<{ value: string; label: string }>` |    NO    | A set of fields to be shown in the auxiliary fields of the pass                                                      |
| codeAlt              |                 `string`                  |    NO    | Barcode Alternative Text                                                                                             |
| qrText               |                 `string`                  |    NO    | Barcode message                                                                                                      |
| codeType             |           `Barcode["format"]``            |    NO    | Barcode format                                                                                                       |
| transitType          |               `TransitType`               |    NO    | Transit Type. Required for boardingPasses                                                                            |
| thumbnailFile        |                 `string`                  |    NO    | File path of the thumbnail file in the storage bucket. If not available, the storage won't be invoked for this file. |
| logoFile             |                 `string`                  |    NO    | File path of the logo file in the storage bucket. If not available, the storage won't be invoked for this file.      |
