# Fetch data from BigQuery

### Step 1

To start this guide, you'll need a Bearer token from Google Cloud saved as a Secret. If you don't have this from before, please check out the following guide:

{% content-ref url="/pages/siFj4mf1SkaW9SxMkiTX" %}
[Retrieve a Bearer token from Google Cloud](/how-to/integrations/retrieve-bearer-token-from-google-cloud.md)
{% endcontent-ref %}

### Step 2

Go to Appfarm Create -> Services, and select the service you want to use (or create a new one). Then, create a new service endpoint, which will be used to fetch data from BigQuery. Give the endpoint a name and a readable ID.

Go down to "Process action", and click the value field to create a new action. You may name the Action "Process BigQuery".

### Step 3

Inside Actions -> Process BigQuery, add a new Action Node "Web request". Set the following properties:

* **URL:** [https://bigquery.googleapis.com/bigquery/v2/projects/\[bq\_project\_id\]/queries](https://bigquery.googleapis.com/bigquery/v2/projects/peerless-dahlia-344408/queries)
* **Authorization:** Bearer token
* **Auth token:** Data-bind to `Secrets.[The Bearer Token from Google]`
* **Prefix Bearer Keyword:** `true`
* **Body Type:** Raw

Then, set the **Body Content** to the following:&#x20;

```
return {
  "query": "SELECT [column] FROM [bq_project_id].[bq_dataset_name].[bq_table_name]",
  "parameterMode": "NAMED",
  "useLegacySql": false
}
```

To make the response readable for the Result Mapping in Appfarm, you need to flatten the result from BigQuery. To do so, copy/paste this code into the **Result Parser:**

```
//Flatten the result from BigQuery
function convertBQToFlattenResults(schema, rows) {

    let resultRows = []
    let result = {};
    
    function recurse (schemaCur, rowsCur, colName) {
    
        if (Array.isArray(schemaCur) && !Array.isArray(result[colName])) {
            for(let i=0, l=schemaCur.length; i<l; i++) {
                if (colName === "")
                    recurse(schemaCur[i], rowsCur.f[i], colName + schemaCur[i].name)
                else
                    recurse(schemaCur[i], rowsCur.f[i], colName + "." + schemaCur[i].name)
            }    
        }

        if (schemaCur.type && schemaCur.type === "RECORD") {
            if (schemaCur.mode !== "REPEATED") {
                let valIndex = 0
                for (let p in schemaCur.fields) {
                    if (rowsCur.v === null) {
                        recurse(schemaCur.fields[p], rowsCur, colName + "." + schemaCur.fields[p].name)
                    } else {
                        recurse(schemaCur.fields[p], rowsCur.v.f[valIndex], colName + "." + schemaCur.fields[p].name)
                    }
                    
                    valIndex++
                }
            } 
            
            if (schemaCur.mode === "REPEATED") {   
                result[colName] = [] 
                for (let x in rowsCur.v) {
                    recurse(schemaCur.fields, rowsCur.v[x], colName)
                }
            }
        } else {
            if (schemaCur.mode === "REPEATED") {
                if (rowsCur.v !== null) {
                    result[colName] = rowsCur.v.map( (value, index) => { return value.v })
                } else {
                    result[colName] = [ null ]
                }
                
            } else if (Array.isArray(result[colName])) {
                let nextRow = {} 
                for (let j in schemaCur) {
                    nextRow[colName + "." + schemaCur[j].name] = rowsCur.v.f[j].v 
                }
                result[colName].push(nextRow)
            } else {
                if (colName !== "")
                    result[colName] = rowsCur.v
            }
        }
    }

    for (let r=0, rowsCount=rows.length; r<rowsCount; r++) {
        result = {};
        recurse(schema, rows[r], "")
        resultRows.push(result)
    }

    return resultRows
}

let bqQueryApiResult = rawResponseData

let output = convertBQToFlattenResults(bqQueryApiResult.schema.fields, bqQueryApiResult.rows)

return output
```

Finally, add a new **Result Mapping.** Choose the data source you'd like to write data to, and write the column names from BigQuery into the value fields on the Object Class Properties.

### Run the service

Now everything is set up to retrieve data from BigQuery. Make sure to first retrieve the Bearer token. Then, run the service to fetch data from BigQuery. If everything is set up correctly, all the objects requested in your query will be added to the selected data source.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.appfarm.io/how-to/integrations/fetch-data-from-bigquery.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
