Merge pull request #4864 from mslourens/google_firebase_integration
Google firebase integration
This commit is contained in:
commit
4550631c1b
|
@ -0,0 +1,54 @@
|
|||
<script>
|
||||
export let width = "100"
|
||||
export let height = "100"
|
||||
</script>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="23 6 469 132"
|
||||
{width}
|
||||
{height}
|
||||
>
|
||||
<defs id="defs202">
|
||||
<linearGradient id="a" x1="-3.49%" x2="100.83%" y1="17.02%" y2="92.9%">
|
||||
<stop offset="0%" stop-color="#fff" stop-opacity=".1" id="stop192" />
|
||||
<stop offset="14%" stop-color="#fff" stop-opacity=".08" id="stop194" />
|
||||
<stop offset="61%" stop-color="#fff" stop-opacity=".02" id="stop196" />
|
||||
<stop offset="100%" stop-color="#fff" stop-opacity="0" id="stop198" />
|
||||
</linearGradient>
|
||||
<path
|
||||
id="b"
|
||||
d="M106.687 35.2742c-.186-1.0977-.967-2-2.0244-2.338s-2.2148-.057-3.0002.73L86.2473 49.166l-12.12-23.1455c-.5133-.9786-1.525-1.5914-2.6273-1.5914s-2.114.6128-2.6273 1.5914l-6.6277 12.656L45.62 7.5726c-.603-1.1297-1.8588-1.746-3.118-1.5297s-2.2394 1.216-2.4335 2.4827L24 111.701l42.9727 24.1654c2.6985 1.5113 5.985 1.5113 8.6836 0L119 111.701l-12.313-76.427z"
|
||||
/>
|
||||
</defs>
|
||||
<g id="g305" transform="matrix(2.9011579,0,0,2.9011579,43.533284,-135.93685)">
|
||||
<path
|
||||
fill="#ffa000"
|
||||
d="M 23.8266,111.7182 39.9588,8.4901 c 0.1972,-1.266 1.1818,-2.264 2.445,-2.4786 1.2632,-0.2146 2.522,0.4028 3.126,1.5327 L 62.2133,38.6615 68.8633,26 c 0.515,-0.979 1.5303,-1.592 2.6366,-1.592 1.1063,0 2.1215,0.613 2.6366,1.592 l 45.0227,85.718 H 23.8266 Z"
|
||||
id="path204"
|
||||
/>
|
||||
<path
|
||||
fill="#f57c00"
|
||||
d="M 79.566,71.5074 62.2124,38.6472 23.8334,111.7187 Z"
|
||||
id="path206"
|
||||
/>
|
||||
<path
|
||||
fill="#ffca28"
|
||||
d="m 119.1666,111.7187 -12.356,-76.4603 c -0.1867,-1.098 -0.9703,-2 -2.0315,-2.34 -1.0612,-0.34 -2.2226,-0.057 -3.0107,0.7302 l -77.935,78.069 43.1234,24.1834 c 2.708,1.512 6.006,1.512 8.714,0 l 43.4958,-24.1834 z"
|
||||
id="path208"
|
||||
/>
|
||||
<path
|
||||
fill="#ffffff"
|
||||
fill-opacity="0.2"
|
||||
d="m 106.8105,35.2584 c -0.1867,-1.098 -0.9703,-2 -2.0315,-2.34 -1.0612,-0.34 -2.2226,-0.057 -3.0107,0.7302 L 86.3,49.1562 74.1365,26 c -0.515,-0.979 -1.5303,-1.592 -2.6366,-1.592 -1.1063,0 -2.1215,0.613 -2.6366,1.592 L 62.2133,38.6615 45.529,7.5447 C 44.924,6.4145 43.6637,5.7981 42.399,6.0143 41.1343,6.2305 40.153,7.231 39.958,8.498 L 23.8333,111.7187 h -0.052 l 0.052,0.0596 0.4245,0.2085 77.488,-77.5775 c 0.7877,-0.7915 1.952,-1.076 3.016,-0.737 1.064,0.339 1.849,1.2445 2.0338,2.3457 l 12.2518,75.775 0.1192,-0.0745 -12.356,-76.4603 z M 23.9748,111.5772 39.9655,9.228 c 0.1948,-1.267 1.1784,-2.2675 2.442,-2.4837 1.2636,-0.2162 2.524,0.4 3.13,1.5304 L 62.22,39.392 68.87,26.7305 c 0.515,-0.979 1.5303,-1.592 2.6366,-1.592 1.1063,0 2.1215,0.613 2.6366,1.592 l 11.9167,22.664 -62.0858,62.1827 z"
|
||||
id="path210"
|
||||
/>
|
||||
<path
|
||||
fill="#a52714"
|
||||
opacity="0.2"
|
||||
d="m 75.6708,135.1722 c -2.708,1.512 -6.006,1.512 -8.714,0 l -43.0192,-24.1162 -0.1043,0.663 43.1234,24.176 c 2.708,1.512 6.006,1.512 8.714,0 l 43.4958,-24.176 -0.1117,-0.6852 -43.384,24.1387 z"
|
||||
id="path212"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="23 6 469 132"
|
||||
width="100"
|
||||
height="100"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs202">
|
||||
<linearGradient
|
||||
id="a"
|
||||
x1="-3.49%"
|
||||
x2="100.83%"
|
||||
y1="17.02%"
|
||||
y2="92.9%">
|
||||
<stop
|
||||
offset="0%"
|
||||
stop-color="#fff"
|
||||
stop-opacity=".1"
|
||||
id="stop192" />
|
||||
<stop
|
||||
offset="14%"
|
||||
stop-color="#fff"
|
||||
stop-opacity=".08"
|
||||
id="stop194" />
|
||||
<stop
|
||||
offset="61%"
|
||||
stop-color="#fff"
|
||||
stop-opacity=".02"
|
||||
id="stop196" />
|
||||
<stop
|
||||
offset="100%"
|
||||
stop-color="#fff"
|
||||
stop-opacity="0"
|
||||
id="stop198" />
|
||||
</linearGradient>
|
||||
<path
|
||||
id="b"
|
||||
d="M106.687 35.2742c-.186-1.0977-.967-2-2.0244-2.338s-2.2148-.057-3.0002.73L86.2473 49.166l-12.12-23.1455c-.5133-.9786-1.525-1.5914-2.6273-1.5914s-2.114.6128-2.6273 1.5914l-6.6277 12.656L45.62 7.5726c-.603-1.1297-1.8588-1.746-3.118-1.5297s-2.2394 1.216-2.4335 2.4827L24 111.701l42.9727 24.1654c2.6985 1.5113 5.985 1.5113 8.6836 0L119 111.701l-12.313-76.427z" />
|
||||
</defs>
|
||||
<g
|
||||
id="g305"
|
||||
transform="matrix(2.9011579,0,0,2.9011579,43.533284,-135.93685)">
|
||||
<path
|
||||
fill="#ffa000"
|
||||
d="M 23.8266,111.7182 39.9588,8.4901 c 0.1972,-1.266 1.1818,-2.264 2.445,-2.4786 1.2632,-0.2146 2.522,0.4028 3.126,1.5327 L 62.2133,38.6615 68.8633,26 c 0.515,-0.979 1.5303,-1.592 2.6366,-1.592 1.1063,0 2.1215,0.613 2.6366,1.592 l 45.0227,85.718 H 23.8266 Z"
|
||||
id="path204" />
|
||||
<path
|
||||
fill="#f57c00"
|
||||
d="M 79.566,71.5074 62.2124,38.6472 23.8334,111.7187 Z"
|
||||
id="path206" />
|
||||
<path
|
||||
fill="#ffca28"
|
||||
d="m 119.1666,111.7187 -12.356,-76.4603 c -0.1867,-1.098 -0.9703,-2 -2.0315,-2.34 -1.0612,-0.34 -2.2226,-0.057 -3.0107,0.7302 l -77.935,78.069 43.1234,24.1834 c 2.708,1.512 6.006,1.512 8.714,0 l 43.4958,-24.1834 z"
|
||||
id="path208" />
|
||||
<path
|
||||
fill="#ffffff"
|
||||
fill-opacity="0.2"
|
||||
d="m 106.8105,35.2584 c -0.1867,-1.098 -0.9703,-2 -2.0315,-2.34 -1.0612,-0.34 -2.2226,-0.057 -3.0107,0.7302 L 86.3,49.1562 74.1365,26 c -0.515,-0.979 -1.5303,-1.592 -2.6366,-1.592 -1.1063,0 -2.1215,0.613 -2.6366,1.592 L 62.2133,38.6615 45.529,7.5447 C 44.924,6.4145 43.6637,5.7981 42.399,6.0143 41.1343,6.2305 40.153,7.231 39.958,8.498 L 23.8333,111.7187 h -0.052 l 0.052,0.0596 0.4245,0.2085 77.488,-77.5775 c 0.7877,-0.7915 1.952,-1.076 3.016,-0.737 1.064,0.339 1.849,1.2445 2.0338,2.3457 l 12.2518,75.775 0.1192,-0.0745 -12.356,-76.4603 z M 23.9748,111.5772 39.9655,9.228 c 0.1948,-1.267 1.1784,-2.2675 2.442,-2.4837 1.2636,-0.2162 2.524,0.4 3.13,1.5304 L 62.22,39.392 68.87,26.7305 c 0.515,-0.979 1.5303,-1.592 2.6366,-1.592 1.1063,0 2.1215,0.613 2.6366,1.592 l 11.9167,22.664 -62.0858,62.1827 z"
|
||||
id="path210" />
|
||||
<path
|
||||
fill="#a52714"
|
||||
opacity="0.2"
|
||||
d="m 75.6708,135.1722 c -2.708,1.512 -6.006,1.512 -8.714,0 l -43.0192,-24.1162 -0.1043,0.663 43.1234,24.176 c 2.708,1.512 6.006,1.512 8.714,0 l 43.4958,-24.176 -0.1117,-0.6852 -43.384,24.1387 z"
|
||||
id="path212" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
|
@ -12,6 +12,7 @@ import Rest from "./Rest.svelte"
|
|||
import Budibase from "./Budibase.svelte"
|
||||
import Oracle from "./Oracle.svelte"
|
||||
import GoogleSheets from "./GoogleSheets.svelte"
|
||||
import Firebase from "./Firebase.svelte"
|
||||
|
||||
export default {
|
||||
BUDIBASE: Budibase,
|
||||
|
@ -28,4 +29,5 @@ export default {
|
|||
REST: Rest,
|
||||
ORACLE: Oracle,
|
||||
GOOGLE_SHEETS: GoogleSheets,
|
||||
FIREBASE: Firebase,
|
||||
}
|
||||
|
|
|
@ -178,6 +178,7 @@ export const IntegrationTypes = {
|
|||
ORACLE: "ORACLE",
|
||||
INTERNAL: "INTERNAL",
|
||||
GOOGLE_SHEETS: "GOOGLE_SHEETS",
|
||||
FIREBASE: "FIREBASE",
|
||||
}
|
||||
|
||||
export const IntegrationNames = {
|
||||
|
@ -195,6 +196,7 @@ export const IntegrationNames = {
|
|||
[IntegrationTypes.ORACLE]: "Oracle",
|
||||
[IntegrationTypes.INTERNAL]: "Internal",
|
||||
[IntegrationTypes.GOOGLE_SHEETS]: "Google Sheets",
|
||||
[IntegrationTypes.FIREBASE]: "Firebase",
|
||||
}
|
||||
|
||||
export const SchemaTypeOptions = [
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
"@bull-board/api": "^3.7.0",
|
||||
"@bull-board/koa": "^3.7.0",
|
||||
"@elastic/elasticsearch": "7.10.0",
|
||||
"@google-cloud/firestore": "^5.0.2",
|
||||
"@koa/router": "8.0.0",
|
||||
"@sendgrid/mail": "7.1.1",
|
||||
"@sentry/node": "^6.0.0",
|
||||
|
|
|
@ -48,6 +48,7 @@ export enum SourceNames {
|
|||
REST = "REST",
|
||||
ORACLE = "ORACLE",
|
||||
GOOGLE_SHEETS = "GOOGLE_SHEETS",
|
||||
FIREBASE = "FIREBASE",
|
||||
}
|
||||
|
||||
export enum IncludeRelationships {
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
import {
|
||||
DatasourceFieldTypes,
|
||||
Integration,
|
||||
QueryTypes,
|
||||
} from "../definitions/datasource"
|
||||
import { IntegrationBase } from "./base/IntegrationBase"
|
||||
import { Firestore, WhereFilterOp } from "@google-cloud/firestore"
|
||||
|
||||
module Firebase {
|
||||
interface FirebaseConfig {
|
||||
email: string
|
||||
privateKey: string
|
||||
projectId: string
|
||||
serviceAccount?: string
|
||||
}
|
||||
|
||||
const SCHEMA: Integration = {
|
||||
docs: "https://firebase.google.com/docs/firestore/quickstart",
|
||||
friendlyName: "Firestore",
|
||||
description:
|
||||
"Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud.",
|
||||
datasource: {
|
||||
email: {
|
||||
type: DatasourceFieldTypes.STRING,
|
||||
required: true,
|
||||
},
|
||||
privateKey: {
|
||||
type: DatasourceFieldTypes.STRING,
|
||||
required: true,
|
||||
},
|
||||
projectId: {
|
||||
type: DatasourceFieldTypes.STRING,
|
||||
required: true,
|
||||
},
|
||||
serviceAccount: {
|
||||
type: DatasourceFieldTypes.JSON,
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
query: {
|
||||
create: {
|
||||
type: QueryTypes.JSON,
|
||||
},
|
||||
read: {
|
||||
type: QueryTypes.JSON,
|
||||
},
|
||||
update: {
|
||||
type: QueryTypes.JSON,
|
||||
},
|
||||
delete: {
|
||||
type: QueryTypes.JSON,
|
||||
},
|
||||
},
|
||||
extra: {
|
||||
collection: {
|
||||
displayName: "Collection",
|
||||
type: DatasourceFieldTypes.STRING,
|
||||
required: true,
|
||||
},
|
||||
filterField: {
|
||||
displayName: "Filter field",
|
||||
type: DatasourceFieldTypes.STRING,
|
||||
required: false,
|
||||
},
|
||||
filter: {
|
||||
displayName: "Filter comparison",
|
||||
type: DatasourceFieldTypes.LIST,
|
||||
required: false,
|
||||
data: {
|
||||
read: [
|
||||
"==",
|
||||
"<",
|
||||
"<=",
|
||||
"==",
|
||||
"!=",
|
||||
">=",
|
||||
">",
|
||||
"array-contains",
|
||||
"in",
|
||||
"not-in",
|
||||
"array-contains-any",
|
||||
],
|
||||
},
|
||||
},
|
||||
filterValue: {
|
||||
displayName: "Filter value",
|
||||
type: DatasourceFieldTypes.STRING,
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
class FirebaseIntegration implements IntegrationBase {
|
||||
private config: FirebaseConfig
|
||||
private db: Firestore
|
||||
|
||||
constructor(config: FirebaseConfig) {
|
||||
this.config = config
|
||||
if (config.serviceAccount) {
|
||||
const serviceAccount = JSON.parse(config.serviceAccount)
|
||||
this.db = new Firestore({
|
||||
projectId: serviceAccount.project_id,
|
||||
credentials: {
|
||||
client_email: serviceAccount.client_email,
|
||||
private_key: serviceAccount.private_key,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
this.db = new Firestore({
|
||||
projectId: config.projectId,
|
||||
credentials: {
|
||||
client_email: config.email,
|
||||
private_key: config.privateKey,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async create(query: { json: object; extra: { [key: string]: string } }) {
|
||||
try {
|
||||
const documentReference = this.db
|
||||
.collection(query.extra.collection)
|
||||
.doc()
|
||||
await documentReference.set({ ...query.json, id: documentReference.id })
|
||||
const snapshot = await documentReference.get()
|
||||
return snapshot.data()
|
||||
} catch (err) {
|
||||
console.error("Error writing to Firestore", err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
async read(query: { json: object; extra: { [key: string]: string } }) {
|
||||
try {
|
||||
let snapshot
|
||||
const collectionRef = this.db.collection(query.extra.collection)
|
||||
if (
|
||||
query.extra.filterField &&
|
||||
query.extra.filter &&
|
||||
query.extra.filterValue
|
||||
) {
|
||||
snapshot = await collectionRef
|
||||
.where(
|
||||
query.extra.filterField,
|
||||
query.extra.filter as WhereFilterOp,
|
||||
query.extra.filterValue
|
||||
)
|
||||
.get()
|
||||
} else {
|
||||
snapshot = await collectionRef.get()
|
||||
}
|
||||
const result: any[] = []
|
||||
snapshot.forEach(doc => result.push(doc.data()))
|
||||
|
||||
return result
|
||||
} catch (err) {
|
||||
console.error("Error querying Firestore", err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
async update(query: {
|
||||
json: Record<string, any>
|
||||
extra: { [key: string]: string }
|
||||
}) {
|
||||
try {
|
||||
await this.db
|
||||
.collection(query.extra.collection)
|
||||
.doc(query.json.id)
|
||||
.update(query.json)
|
||||
|
||||
return (
|
||||
await this.db
|
||||
.collection(query.extra.collection)
|
||||
.doc(query.json.id)
|
||||
.get()
|
||||
).data()
|
||||
} catch (err) {
|
||||
console.error("Error writing to firebase", err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
async delete(query: {
|
||||
json: { id: string }
|
||||
extra: { [key: string]: string }
|
||||
}) {
|
||||
try {
|
||||
await this.db
|
||||
.collection(query.extra.collection)
|
||||
.doc(query.json.id)
|
||||
.delete()
|
||||
return true
|
||||
} catch (err) {
|
||||
console.error("Error writing to mongodb", err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
schema: SCHEMA,
|
||||
integration: FirebaseIntegration,
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ const mysql = require("./mysql")
|
|||
const arangodb = require("./arangodb")
|
||||
const rest = require("./rest")
|
||||
const googlesheets = require("./googlesheets")
|
||||
const firebase = require("./firebase")
|
||||
const { SourceNames } = require("../definitions/datasource")
|
||||
const environment = require("../environment")
|
||||
|
||||
|
@ -25,6 +26,7 @@ const DEFINITIONS = {
|
|||
[SourceNames.MYSQL]: mysql.schema,
|
||||
[SourceNames.ARANGODB]: arangodb.schema,
|
||||
[SourceNames.REST]: rest.schema,
|
||||
[SourceNames.FIREBASE]: firebase.schema,
|
||||
}
|
||||
|
||||
const INTEGRATIONS = {
|
||||
|
@ -39,6 +41,7 @@ const INTEGRATIONS = {
|
|||
[SourceNames.MYSQL]: mysql.integration,
|
||||
[SourceNames.ARANGODB]: arangodb.integration,
|
||||
[SourceNames.REST]: rest.integration,
|
||||
[SourceNames.FIREBASE]: firebase.integration,
|
||||
}
|
||||
|
||||
// optionally add oracle integration if the oracle binary can be installed
|
||||
|
|
Loading…
Reference in New Issue