Skip to content

Commit

Permalink
Added custom data source recipe
Browse files Browse the repository at this point in the history
  • Loading branch information
fgatti675 committed May 16, 2023
1 parent 076ed47 commit 6edcddc
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 4 deletions.
67 changes: 67 additions & 0 deletions example/src/docs/recipes/custom_datasource/custom_datasource.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import {
CMSType,
DataSource,
DeleteEntityProps,
Entity,
FetchCollectionProps,
FetchEntityProps,
ResolvedProperty,
SaveEntityProps,
useFirestoreDataSource
} from "firecms";
import { FirebaseApp } from "firebase/app";

type CustomDataSourceProps = { firebaseApp?: FirebaseApp };

/**
* This is an example of a custom data source.
* It is a React Hook that returns a {@link DataSource} object.
* @param firebaseApp
*/
export function useCustomDatasource({ firebaseApp }: CustomDataSourceProps): DataSource {

const firestoreDataSource = useFirestoreDataSource({
firebaseApp
});

return {
fetchCollection<M extends {
[Key: string]: CMSType
}>(props: FetchCollectionProps<M>): Promise<Entity<M>[]> {
if (props.path === "your_path_custom") {
// make your custom http call and return your Entities
}
return firestoreDataSource.fetchCollection(props);
},
fetchEntity<M extends {
[Key: string]: CMSType
}>(props: FetchEntityProps<M>): Promise<Entity<M> | undefined> {
if (props.path === "your_path_custom") {
// make your custom http call and return your Entities
}
return firestoreDataSource.fetchEntity(props);
},
saveEntity<M extends {
[Key: string]: CMSType
}>(props: SaveEntityProps<M>): Promise<Entity<M>> {
if (props.path === "your_path_custom") {
// make your custom http call and return your Entities
}
return firestoreDataSource.saveEntity(props);
},
deleteEntity<M extends {
[Key: string]: CMSType
}>(props: DeleteEntityProps<M>): Promise<void> {
return firestoreDataSource.deleteEntity(props);
},
checkUniqueField(path: string, name: string, value: any, property: ResolvedProperty, entityId?: string): Promise<boolean> {
return firestoreDataSource.checkUniqueField(path, name, value, property, entityId);
},
generateEntityId(path: string) {
return firestoreDataSource.generateEntityId(path);
},
countEntities(path: string): Promise<number> {
return firestoreDataSource.countEntities(path);
}
}
}
10 changes: 7 additions & 3 deletions lib/src/core/FireCMS.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ import {
import {
FireCMSContextInstance,
useFireCMSContext,
useModeController,
useSnackbarController
useModeController
} from "../hooks";
import { CenteredView, ErrorView } from "./components";
import { StorageSourceContext } from "./contexts/StorageSourceContext";
Expand All @@ -44,10 +43,15 @@ const DEFAULT_COLLECTION_PATH = "/c";
* If you are using independent components of the CMS
* you need to wrap them with this main component, so the internal hooks work.
*
* This is the main component of FireCMS. It acts as the provider of all the
* internal contexts and hooks.
*
* You only need to use this component if you are building a custom app.
* In most cases you can just use the {@link FirebaseCMSApp} component.
*
* @constructor
* @category Core
*/

export function FireCMS<UserType extends User>(props: FireCMSProps<UserType>) {

const modeController = useModeController();
Expand Down
58 changes: 58 additions & 0 deletions website/docs/recipes/custom_datasource.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
id: custom_datasource
title: Use a custom data source
sidebar_label: Custom data source
---

FireCMS is based on the idea of **declarative** data sources. This means that
you can define your collections and entities in a declarative way, and FireCMS
will take care of the rest. We provide a default datasource that works with
Firestore, but you can also use your own data sources.

## Custom data sources

FireCMS allows you to use your own data sources. This is useful if you want to
use FireCMS with a different database, or if you want to use a different
Firestore instance.

Data sources are implemented as objects that implement the
[`DataSource`](./api/interfaces/DataSource) interface.

Since FireCMS is a CMS based on React, you can use the hooks provided by FireCMS to
develop your own data sources.

The default datasource is implemented in the [`useFirestoreDataSource`](./api/functions/useFirestoreDataSource)
hook. You can call this hook from your own data source to get the default
implementation and extend it. When defining your own data source, you need
to implement all the methods defined in the [`DataSource`](./api/interfaces/DataSource)
interface.

## Example custom datasource

Let's define a custom data source that will allow us to override the default
implementation when fetching and saving data for a specific path only:

import CodeBlock from "@theme/CodeBlock";
import CustomDataSource
from "!!raw-loader!firecms-example/src/docs/recipes/custom_datasource/custom_datasource";

<CodeBlock language="tsx">{CustomDataSource}</CodeBlock>

## Using a custom data source

Once you have defined your custom data source, you can use it in your
custom [`FireCMS`](./api/interfaces/FireCMS) instance (keep in mind that you can't use a
custom data source with `FirebaseCMSApp`).

You will need to create a custom app, and use your custom data source when
creating the `FireCMS` instance.

Check the [Custom CMS app](../custom_cms_app) instructions to learn how to create a custom app.
Replace the `useFirestoreDataSource` hook with your custom data source.

:::tip
You can also customise in the same way the other components used internally by
FireCMS.
:::


2 changes: 1 addition & 1 deletion website/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ module.exports = {
label: "Recipes",
collapsed: false,
items: [
// 'recipes/recipes_index',
"recipes/building_a_blog",
"recipes/copy_entity",
"recipes/custom_datasource",
"recipes/documents_as_subcollections",
]
},
Expand Down

0 comments on commit 6edcddc

Please sign in to comment.