Skip to content

[WIP] Tried adding automatic index creation #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions extension.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ roles:
- role: datastore.user
reason: >-
Allows Slack Support Chat to store support messages in Cloud Firestore.
- role: datastore.indexAdmin
reason: >-
Allows the extension to create a composite index on install.

# In the `resources` field, list each of your extension's functions, including the trigger for each function.
# Learn more in the docs:
Expand All @@ -58,6 +61,18 @@ resources:
properties:
httpsTrigger: {}

- name: createSupportIndex
type: firebaseextensions.v1beta.function
description: >-
Lifecycle task that creates the required collection group index on install.
properties:
taskQueueTrigger: {}

lifecycleEvents:
onInstall:
function: createSupportIndex
processingMessage: "Creating Firestore composite index for Slack Support Chat…"

# In the `params` field, set up your extension's user-configured parameters.
# Learn more in the docs:
# https://firebase.google.com/docs/extensions/reference/extension-yaml#params-field
Expand Down
1 change: 1 addition & 0 deletions functions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@slack/web-api": "^7.9.1",
"firebase-admin": "^12.6.0",
"firebase-functions": "^6.0.1",
"google-auth-library": "^9.15.1",
"node-emoji": "^2.2.0"
},
"devDependencies": {
Expand Down
2 changes: 2 additions & 0 deletions functions/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { getFirestore } from 'firebase-admin/firestore';
initializeApp();
export const db = getFirestore();

import { createSupportIndex } from './installFunctions';
import { onSupportMessageCreated, slackSupportEvents } from './supportFunctions';

export { createSupportIndex };
export { onSupportMessageCreated, slackSupportEvents };
63 changes: 63 additions & 0 deletions functions/src/installFunctions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { onTaskDispatched } from 'firebase-functions/v2/tasks';
import { GoogleAuth } from "google-auth-library";
import { logger } from 'firebase-functions';

/**
* Lifecycle task (`taskQueueTrigger`) that creates a composite index on the
* `support` collection group for the `slackThreadTs` field.
*
* • Runs once at extension install.
* • Ignores `ALREADY_EXISTS` errors to keep the install idempotent.
*/
export const createSupportIndex = onTaskDispatched(
{
retryConfig: { maxAttempts: 3 }
},
async () => {
logger.info('createSupportIndex(): Function started');

// MARK: - Get environment variables

const projectId = process.env.GCP_PROJECT ?? process.env.PROJECT_ID;
const configPath = process.env.CONFIG_PATH;
if (!projectId || !configPath) {
logger.error('createSupportIndex(): Project ID or config path is not set', { projectId, configPath });
return;
}

const configSegments = configPath.split('/');
const lastCollection = configSegments[configSegments.length - 2];
const url = `https://firestore.googleapis.com/v1/projects/${projectId}/databases/(default)/collectionGroups/${lastCollection}/indexes`;

// MARK: - Composite index definition

const body = {
fields: [
{ fieldPath: "slackThreadTs", order: "ASCENDING" },
{ fieldPath: "__name__", order: "ASCENDING" }
],
queryScope: "COLLECTION_GROUP"
};

// MARK: - Acquire an access token and call Firestore Admin REST API

const auth = new GoogleAuth({
scopes: ["https://www.googleapis.com/auth/cloud-platform"]
});
const client = await auth.getClient();

// MARK: - Send the request

try {
await client.request({ url, method: "POST", data: body });
logger.info(`createSupportIndex(): Support index creation request sent for collection group '${lastCollection}'`);
} catch (err: any) {
// 409 == ALREADY_EXISTS; any other status re‑throws to let the task retry
if (err.response?.status === 409) {
logger.info("createSupportIndex(): Support index already exists – nothing to do");
} else {
logger.error("createSupportIndex(): Index creation failed", err.response?.data ?? err);
throw err; // triggers task retry / surfacing to installer
}
}
});