{"id":13677999,"url":"https://github.com/FirebaseGoodies/FireAdmin","last_synced_at":"2025-04-29T12:32:53.048Z","repository":{"id":38585068,"uuid":"249248382","full_name":"FirebaseGoodies/FireAdmin","owner":"FirebaseGoodies","description":":seedling: A mini headless CMS built with Angular \u0026 Firebase","archived":false,"fork":false,"pushed_at":"2023-03-03T11:46:41.000Z","size":5887,"stargazers_count":79,"open_issues_count":19,"forks_count":20,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-09-18T20:54:59.707Z","etag":null,"topics":["admin","admin-dashboard","angular","cms","firebase","firestore","headless-cms"],"latest_commit_sha":null,"homepage":"https://firebasegoodies.github.io/FireAdmin/demo/login?email=guest@fireadmin.com\u0026password=fireadmin","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FirebaseGoodies.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":"https://www.paypal.me/axeldev"}},"created_at":"2020-03-22T18:37:35.000Z","updated_at":"2024-07-01T07:01:40.000Z","dependencies_parsed_at":"2024-02-29T06:47:47.910Z","dependency_job_id":null,"html_url":"https://github.com/FirebaseGoodies/FireAdmin","commit_stats":null,"previous_names":["axel-dev/fireadmin"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FirebaseGoodies%2FFireAdmin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FirebaseGoodies%2FFireAdmin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FirebaseGoodies%2FFireAdmin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FirebaseGoodies%2FFireAdmin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FirebaseGoodies","download_url":"https://codeload.github.com/FirebaseGoodies/FireAdmin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224173431,"owners_count":17268110,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["admin","admin-dashboard","angular","cms","firebase","firestore","headless-cms"],"created_at":"2024-08-02T13:00:49.240Z","updated_at":"2024-11-11T20:30:48.610Z","avatar_url":"https://github.com/FirebaseGoodies.png","language":"TypeScript","readme":"# \u003cimg src=\"projects/demo/src/assets/images/logo.svg\" alt=\"icon\" width=\"38\" align=\"top\" /\u003e FireAdmin\n\n[![NPM version](https://img.shields.io/npm/v/ng-fire-admin)](https://www.npmjs.com/package/ng-fire-admin)\n[![Downloads](https://img.shields.io/npm/dt/ng-fire-admin)](https://www.npmjs.com/package/ng-fire-admin)\n[![License](https://img.shields.io/npm/l/ng-fire-admin)](LICENSE)\n[![Donate](https://img.shields.io/badge/PayPal-Donate-gray.svg?style=flat\u0026logo=paypal\u0026colorA=0071bb\u0026logoColor=fff)](https://www.paypal.me/axeldev)\n\nA minimalistic headless CMS built around Angular \u0026 Firebase.\n\n![screenshot](https://github.com/FirebaseGoodies/FireAdmin/blob/master/screenshots/dashboard.png?raw=true)\n\n## Demo\n\n[FireAdmin Demo](https://firebasegoodies.github.io/FireAdmin/demo/login?email=guest@fireadmin.com\u0026password=fireadmin)\n\n## Features\n\n- Simple \u0026 minimalistic\n- Customizable\n- Responsive\n- Internationalization ready\n- Easy/automated updates (via npm)\n\n## Installation\n\n```\nnpm install --save ng-fire-admin\n```\n\n## Usage\n\n\u003e It's recommended to use a [multi-project workspace](https://angular.io/guide/file-structure#multiple-projects) with basically 2 main applications (one for the frontend part \u0026 the other for the backend) to avoid any potential conflicts, then apply the following changes on your backend app:\n\n\u003cdetails\u003e\n  \u003csummary\u003eMulti-project creation steps\u003c/summary\u003e\n  \n  ```bash\n    ng new my-workspace --createApplication=\"false\"\n    cd my-workspace\n    ng generate application backend --defaults --routing=true\n    // you can add the frontend app the same way: ng generate application frontend --defaults --routing=true\n    npm install --save ng-fire-admin\n  ```\n\u003c/details\u003e\n\n**1**. Setup your firebase project:\n\n- Start by adding a new project in your [firebase console](https://console.firebase.google.com).\n\n- Enable Authentication by email \u0026 password.\n\n- Add a database to your project.\n\n- [Get your firebase configuration](https://support.google.com/firebase/answer/7015592#web).\n\n**2**. Add your firebase configuration in `environment.ts`:\n\n```diff\n  export const environment = {\n    production: false,\n+   firebase: {\n+     apiKey: \"\u003cAPI_KEY\u003e\",\n+     authDomain: \"\u003cPROJECT_ID\u003e.firebaseapp.com\",\n+     databaseURL: \"https://\u003cDATABASE_NAME\u003e.firebaseio.com\",\n+     projectId: \"\u003cPROJECT_ID\u003e\",\n+     storageBucket: \"\u003cBUCKET\u003e.appspot.com\",\n+     messagingSenderId: \"\u003cSENDER_ID\u003e\",\n+     appId: \"\u003cAPP_ID\u003e\"\n+   }\n  };\n```\n\n**3**. Register the `FireAdminModule` in a module, for example app module:\n\n```diff\n  import { BrowserModule } from '@angular/platform-browser';\n  import { NgModule } from '@angular/core';\n\n  import { AppRoutingModule } from './app-routing.module';\n  import { AppComponent } from './app.component';\n+ import { FireAdminModule } from 'ng-fire-admin';\n+ import { environment } from '../environments/environment';\n\n  @NgModule({\n    declarations: [AppComponent],\n    imports: [\n      BrowserModule,\n      AppRoutingModule,\n+     FireAdminModule.initialize(environment.firebase)\n    ],\n    providers: [],\n    bootstrap: [AppComponent]\n  })\n  export class AppModule {}\n```\n\n**4**. Setup a simple routing as below:\n\n```diff\n  import { NgModule } from '@angular/core';\n  import { Routes, RouterModule } from '@angular/router';\n\n  const routes: Routes = [\n+   {\n+     path: 'admin',\n+     loadChildren: () =\u003e import('ng-fire-admin').then(m =\u003e m.FireAdminModule)\n+   },\n+   {\n+     path: '**',\n+     redirectTo: 'admin'\n+   }\n  ];\n\n  @NgModule({\n    imports: [RouterModule.forRoot(routes)],\n    exports: [RouterModule]\n  })\n  export class AppRoutingModule { }\n```\n\n**5**. Edit your main component template (generally `app.component.html`) \u0026 keep only the `\u003crouter-outlet\u003e\u003c/router-outlet\u003e` line:\n\n```diff\n+ \u003crouter-outlet\u003e\u003c/router-outlet\u003e\n```\n\n**6**. Add the following styles \u0026 scripts entries to `angular.json`:\n\n```diff\n  \"assets\": [\n    \"projects/backend/src/favicon.ico\",\n    \"projects/backend/src/assets\"\n  ],\n  \"styles\": [\n    \"projects/backend/src/styles.css\",\n+   \"node_modules/@fortawesome/fontawesome-free/css/all.min.css\",\n+   \"node_modules/material-icons-font/material-icons-font.css\",\n+   \"node_modules/bootstrap/dist/css/bootstrap.min.css\",\n+   \"node_modules/datatables.net-responsive-dt/css/responsive.dataTables.min.css\",\n+   \"node_modules/quill/dist/quill.snow.css\"\n  ],\n  \"scripts\": [\n+   \"node_modules/jquery/dist/jquery.min.js\",\n+   \"node_modules/popper.js/dist/umd/popper.min.js\",\n+   \"node_modules/bootstrap/dist/js/bootstrap.min.js\",\n+   \"node_modules/datatables.net/js/jquery.dataTables.min.js\",\n+   \"node_modules/datatables.net-responsive-dt/js/responsive.dataTables.min.js\",\n+   \"node_modules/chart.js/dist/Chart.min.js\",\n+   \"node_modules/shards-ui/dist/js/shards.min.js\",\n+   \"node_modules/quill/dist/quill.min.js\"\n  ]\n```\n\n**7**. You may also need to add the following lines to `polyfills.ts`:\n\n```diff\n  // Add global to window, assigning the value of window itself.\n+ (window as any).global = window;\n```\n\n**8**. In order to protect your database \u0026 storage data, you must set the following rules in your firebase console:\n\n**Firestore Database rules:**\n\n```javascript\nrules_version = '2';\nservice cloud.firestore {\n  match /databases/{database}/documents {\n    match /{collection}/{document}/{path=**} {\n      allow read: if isReadable(collection, document);\n      allow write: if isWritable(collection, document);\n    }\n\n    // Checks if collection/document is readable\n    function isReadable(collection, document) {\n      return isAdmin() || !isReadProtected(collection) || isOwner(document);\n    }\n\n    // Checks if collection is protected against read\n    function isReadProtected(collection) {\n      return collection in ['users'];\n    }\n\n    // Checks if collection/document is writable\n    function isWritable(collection, document) {\n      return isAdmin() || (\n        collection == 'users' \u0026\u0026 isRegistrationEnabled()\n      ) || (\n        isEditor() \u0026\u0026 (!isWriteProtected(collection) || isOwner(document))\n      );\n    }\n\n    // Checks if collection is protected against write\n    function isWriteProtected(collection) {\n      return collection in ['users', 'config'];\n    }\n\n    // Checks if registration is enabled\n    function isRegistrationEnabled() {\n      return !exists(/databases/$(database)/documents/config/registration) || get(/databases/$(database)/documents/config/registration).data.enabled;\n    }\n\n    // User role check functions\n    function isAdmin() {\n      return hasRole('admin');\n    }\n\n    function isEditor() {\n      return hasRole('editor');\n    }\n\n    function isSignedIn() {\n      return request.auth != null;\n    }\n\n    function hasRole(role) {\n      return isSignedIn() \u0026\u0026 get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == role;\n    }\n\n    function isOwner(ownerId) {\n      return isSignedIn() \u0026\u0026 request.auth.uid == ownerId;\n    }\n  }\n}\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eMore basic database rules? (not recommended)\u003c/summary\u003e\n  \n  ```javascript\n    rules_version = '2';\n    service cloud.firestore {\n      match /databases/{database}/documents {\n        match /{collection}/{document=**} {\n          allow read: if collection != 'users' || request.auth != null;\n          allow write: if request.auth != null;\n        }\n      }\n    }\n  ```\n\u003c/details\u003e\n\n**Storage rules:**\n\n```javascript\nrules_version = '2';\nservice firebase.storage {\n  match /b/{bucket}/o {\n    match /{allPaths=**} {\n      allow read;\n      allow write: if request.auth != null;\n    }\n  }\n}\n```\n\n**9**. Launch your project using `ng serve`.\n\nThat's it :tada:, enjoy your ready to use backend app!\n\n\u003c!--\n## Troubleshoot\n\nIn case you encounter one of the following errors while trying to serve or build your app:\n\n```javascript\nCannot find type definition file for 'datatables.net'.\nCannot find namespace 'DataTables'.\n```\n\nJust install the following package:\n\n```\nnpm install --save-dev @types/datatables.net\n```\n--\u003e\n\n## FAQ\n\n**Q: How to get \u0026 display my data on the frontend side?**\n\nA: FireAdmin is [Headless](https://en.wikipedia.org/wiki/Headless_software#Headless_websites), so it only stores/updates your data. This separation of concerns can avoid style/dependency conflicts \u0026 allows you to serve your backend \u0026 frontend apps on different servers.\n\nYou can retrieve the data on your frontend app using [Firebase client API](https://firebase.google.com/docs/reference/js) \u0026 display them in the way you want to.\n\n**Q: Why don't you use Firebase functions to manage `users` through a custom API for example?**\n\nA:\n 1. I just wanted to prove the theory of a serverless CMS using both Angular \u0026 Firebase client side features.\n 2. Firebase functions needs a `blaze` tier to be deployed, which will make the user management not usable/testable for free.\n\n**Q: Do you have any plans to continue this project?**\n\nA: I do, all i need is free time, ambition \u0026 some [:coffee:](https://www.paypal.me/axeldev).\n\n**Q: Cool! i liked your project, how can i help?**\n\nA:\n- If you are a developer \u0026 you feel interested to contribute, i invite you to check the [todo list](#todo) below or to review the source code, as many parts still need to be reworked.\n- If not, then you can give us a :star2: \u0026 why not share the project with your friends.\n\n## ToDo\n\n- [ ] Menus handler\n- [ ] Password reset feature\n- [ ] Posts comments\n- [ ] Posts custom fields\n- [ ] Replace nested components directories with modules\n\n## Build\n\nRun `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.\n\n## Publishing\n\nAfter building your library with `ng build`, go to the dist folder `cd dist/fire-admin` and run `npm publish`.\n\n## Credits\n\n\u003ca target=\"_blank\" href=\"https://icons8.com/icons/set/firebase\"\u003eFirebase icon\u003c/a\u003e by \u003ca target=\"_blank\" href=\"https://icons8.com\"\u003eIcons8\u003c/a\u003e.\n\n## License\n\nThis project is licensed under the [MIT](LICENSE) license.\n","funding_links":["https://www.paypal.me/axeldev"],"categories":["Uncategorized"],"sub_categories":["Uncategorized"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FFirebaseGoodies%2FFireAdmin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FFirebaseGoodies%2FFireAdmin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FFirebaseGoodies%2FFireAdmin/lists"}