feat: cloud functions

This commit is contained in:
Leon Morival 2026-04-19 16:59:09 +02:00
parent ef7d04fe24
commit 9f7dabbe86
10 changed files with 10444 additions and 0 deletions

5
.firebaserc Normal file
View File

@ -0,0 +1,5 @@
{
"projects": {
"default": "expo-starter-9daef"
}
}

16
firebase.json Normal file
View File

@ -0,0 +1,16 @@
{
"functions": [
{
"source": "functions",
"codebase": "default",
"disallowLegacyRuntimeConfig": true,
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log",
"*.local"
]
}
]
}

33
functions/.eslintrc.js Normal file
View File

@ -0,0 +1,33 @@
module.exports = {
root: true,
env: {
es6: true,
node: true,
},
extends: [
"eslint:recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:import/typescript",
"google",
"plugin:@typescript-eslint/recommended",
],
parser: "@typescript-eslint/parser",
parserOptions: {
project: ["tsconfig.json", "tsconfig.dev.json"],
sourceType: "module",
},
ignorePatterns: [
"lib/**", // Ignore built files.
"generated/**", // Ignore generated files.
],
plugins: [
"@typescript-eslint",
"import",
],
rules: {
"quotes": ["error", "double"],
"import/no-unresolved": "off",
"indent": ["error", 2],
},
};

10
functions/.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
# Compiled JavaScript files
lib/**/*.js
lib/**/*.js.map
# TypeScript v1 declaration files
typings/
# Node.js dependency directory
node_modules/
*.local

10286
functions/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

31
functions/package.json Normal file
View File

@ -0,0 +1,31 @@
{
"name": "functions",
"scripts": {
"lint": "ESLINT_USE_FLAT_CONFIG=false eslint --ext .js,.ts src",
"build": "tsc",
"build:watch": "tsc --watch",
"serve": "npm run build && firebase emulators:start --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "24"
},
"main": "lib/index.js",
"dependencies": {
"firebase-admin": "^13.6.0",
"firebase-functions": "^7.0.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.12.0",
"@typescript-eslint/parser": "^5.12.0",
"eslint": "^8.9.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-import": "^2.25.4",
"firebase-functions-test": "^3.4.1",
"typescript": "^6.0.0"
},
"private": true
}

5
functions/src/index.ts Normal file
View File

@ -0,0 +1,5 @@
import {setGlobalOptions} from "firebase-functions/v2";
setGlobalOptions({maxInstances: 10});
export * from "./users";

35
functions/src/users.ts Normal file
View File

@ -0,0 +1,35 @@
import {getApps, initializeApp} from "firebase-admin/app";
import {getAuth} from "firebase-admin/auth";
import * as logger from "firebase-functions/logger";
import {onDocumentDeleted} from "firebase-functions/v2/firestore";
const adminApp = getApps().length > 0 ? getApps()[0] : initializeApp();
export const deleteUserAuthOnUserDocumentDeleted = onDocumentDeleted(
"users/{uid}",
async (event) => {
const uid = event.params.uid;
if (!uid) {
logger.error("Missing uid in users/{uid} delete trigger.");
return;
}
try {
await getAuth(adminApp).deleteUser(uid);
logger.info(
"Deleted auth user after Firestore user deletion.",
{uid}
);
} catch (error) {
logger.error(
"Failed to delete auth user after Firestore user deletion.",
{
uid,
error,
}
);
throw error;
}
}
);

View File

@ -0,0 +1,5 @@
{
"include": [
".eslintrc.js"
]
}

18
functions/tsconfig.json Normal file
View File

@ -0,0 +1,18 @@
{
"compilerOptions": {
"module": "NodeNext",
"esModuleInterop": true,
"moduleResolution": "nodenext",
"noImplicitReturns": true,
"noUnusedLocals": true,
"outDir": "lib",
"rootDir": "src",
"sourceMap": true,
"strict": true,
"target": "es2017"
},
"compileOnSave": true,
"include": [
"src"
]
}