Giter VIP home page Giter VIP logo

saas's Introduction

What is @fireactjs/saas

fireactjs-saas is the extension package for building SaaS web applications with Firebase, Reactjs and Stripe in a simple and fast approach. It is based on the @fireactjs/core package for the user authentication features. Its key features on top of the @fireactjs/core package are:

  • Built-in Stripe subscription integration
  • User permission control on the subscription account level
  • Template base design for easy customization
  • Component base architecture that supports full customization
  • Easy to extend additional features

Live demo

To experience the package, go to https://saas-demo.fireactjs.com

Documentation

For documentation of the package, go to https://fireactjs.com/docs/saas-package/

Installation

Instructions for installing Fireactjs SaaS packages and creating your Reactjs SaaS application with the Fireactjs packages.

Create Reactjs App with Fireactjs Core

Before installing the Fireactjs SaaS packages, you must set up your Reactjs application with the Fireactjs Core package for user authentication. Read Fireactjs Installation Guide.

Install from NPM

The Fireactjs SaaS project comes with two packages: @fireacjts/saas for the Reactjs front-end and @fireactjs/saas-cloud-functions for the server-side Firebase Cloud Functions.

In your Reactjs app root folder, use the following command to install the @fireactjs/saas package:

npm i @fireactjs/saas

In your /functions folder where your Firebase Cloud Functions are located, use the following command to install the @fireactjs/saas-cloud-functions package:

npm i @fireactjs/saas-cloud-functions

Setup Payment Plans

Fireactjs SaaS integrates with Stripe to handle subscription payments. You must have a Stripe account to enable the integration.

In Stripe, create products for your SaaS. Each product can have multiple prices. However, these prices must have the same billing period.

Create a JSON to describe your plans as the example below. Each plan must have an unique id to identify the plan. A plan can contain multiple price IDs from different products in Stripe. In this example, the "enterprise" plan contains two prices which are from two products: license and support.

If the free property is set to true for a plan, the plan will not ask for putting in a credit card. Make sure that all the prices in the plan are "0" in price in Stripe.

If a plan is no longer available for new users, set its legacy property to true and the plan will not be shown in the pricing table.

[
    {
        "id": "free",
        "title": "Free",
        "popular": false,
        "priceIds": [
            "price_1..."
        ],
        "currency": "$",
        "price": 0,
        "frequency": "week",
        "description": [
            "10 users included",
            "2 GB of storage",
            "Help center access",
            "Email support"
        ],
        "free": true,
        "legacy": false
    },
    {
        "id": "pro",
        "title": "Pro",
        "popular": true,
        "priceIds": [
            "price_2..."
        ],
        "currency": "$",
        "price": 10,
        "frequency": "week",
        "description": [
            "20 users included",
            "10 GB of storage",
            "Help center access",
            "Priority email support"
        ],
        "free": false,
        "legacy": false
    },
    {
        "id": "enterprise",
        "title": "Enterprise",
        "popular": false,
        "priceIds": [
            "price_3...",
            "price_4..."
        ],
        "currency": "$",
        "price": 30,
        "frequency": "week",
        "description": [
            "50 users included",
            "30 GB of storage",
            "Help center access",
            "Phone & email support"
        ],
        "free": false,
        "legacy": false
    },
    {
        "id": "legcy",
        "title": "Gold",
        "popular": true,
        "priceIds": [
            "price_2..."
        ],
        "currency": "$",
        "price": 10,
        "frequency": "week",
        "description": [
            "20 users included",
            "10 GB of storage",
            "Help center access",
            "Priority email support"
        ],
        "free": false,
        "legacy": true
    }
]

Setup Stripe Integration

For the cloud functions to receive data from Stripe, you will need to create a webhook endpoint with the cloud function webhook URL https://firebse-location-project-id.cloudfunctions.net/fireactjsSaas-stripeWebHook. Please make sure you replace the domain with your actual Firebase project cloud function domain. Once the webhook is created, you will get an endpoint secret which is needed in the configuration file.

The following Stripe events need to be sent to the endpoint:

customer.subscription.updated
customer.subscription.trial_will_end
customer.subscription.pending_update_expired
customer.subscription.pending_update_applied
customer.subscription.deleted
customer.subscription.created
invoice.created
invoice.deleted
invoice.finalized
invoice.marked_uncollectible
invoice.paid
invoice.payment_action_required
invoice.payment_failed
invoice.payment_succeeded
invoice.sent
invoice.updated
invoice.voided

Create /src/config.json File

Create a file called config.json in the /src folder as the example shows below store the configuration settings.

To integrate with Stripe, the Stripe public API key is required for the stripe.pubblic_api_key property.

The Reactjs application needs the price_id from Stripe to integrate with the Stripe payment plans. The plans will be shown in the pricing table as the property values in the JSON plans. It’s important that the priceId property value of each plan matches the plan’s price_id in Stripe.

{
    "stripe": {
        "public_api_key": "pk_test_..."
    },
    "plans": [
        {
            "id": "free",
            "title": "Free",
            "popular": false,
            "priceIds": [
                "price_1..."
            ],
            "currency": "$",
            "price": 0,
            "frequency": "week",
            "description": [
                "10 users included",
                "2 GB of storage",
                "Help center access",
                "Email support"
            ],
            "free": true,
            "legacy": false
        },
        {
            "id": "pro",
            "title": "Pro",
            "popular": true,
            "priceIds": [
                "price_2..."
            ],
            "currency": "$",
            "price": 10,
            "frequency": "week",
            "description": [
                "20 users included",
                "10 GB of storage",
                "Help center access",
                "Priority email support"
            ],
            "free": false,
            "legacy": false
        },
        {
            "id": "enterprise",
            "title": "Enterprise",
            "popular": false,
            "priceIds": [
                "price_3...",
                "price_4..."
            ],
            "currency": "$",
            "price": 30,
            "frequency": "week",
            "description": [
                "50 users included",
                "30 GB of storage",
                "Help center access",
                "Phone & email support"
            ],
            "free": false,
            "legacy": false
        },
        {
            "id": "legcy",
            "title": "Gold",
            "popular": true,
            "priceIds": [
                "price_2..."
            ],
            "currency": "$",
            "price": 10,
            "frequency": "week",
            "description": [
                "20 users included",
                "10 GB of storage",
                "Help center access",
                "Priority email support"
            ],
            "free": false,
            "legacy": true
        }
    ],
    "permissions": {
        "access": {
            "default": true,
            "admin": false
        },
        "admin": {
            "default": false,
            "admin": true
        }
    },
    "subscription": {
        "singular": "project",
        "plural": "projects"
    }
}

Create /functions/config.json File

In the /functions folder, create a config.json file as the example shows below.

You will need to put in the stripe secret API key and the endpoint secret in the configuration file to integrate the cloud functions with Stripe.

Plans are also needed for the cloud functions similar to the Reactjs application.

For sending new user invites, the mailgun JSON is needed. The details are covered in the next section.

{
    "brand": "My Brand",
    "site_name": "My SaaS App",
    "site_url": "https://app.mydomain.com",
    "sign_in_url": "https://app.mydomain.com/sign-in",
    "sign_up_url": "https://app.mydomain.com/sign-up",
    "stripe": {
        "secret_api_key": "sk_test_...",
        "end_point_secret": "whsec_..."
    },
    "plans": [
        {
            "id": "free",
            "title": "Free",
            "popular": false,
            "priceIds": [
                "price_1..."
            ],
            "currency": "$",
            "price": 0,
            "frequency": "week",
            "description": [
                "10 users included",
                "2 GB of storage",
                "Help center access",
                "Email support"
            ],
            "free": true,
            "legacy": false
        },
        {
            "id": "pro",
            "title": "Pro",
            "popular": true,
            "priceIds": [
                "price_2..."
            ],
            "currency": "$",
            "price": 10,
            "frequency": "week",
            "description": [
                "20 users included",
                "10 GB of storage",
                "Help center access",
                "Priority email support"
            ],
            "free": false,
            "legacy": false
        },
        {
            "id": "enterprise",
            "title": "Enterprise",
            "popular": false,
            "priceIds": [
                "price_3...",
                "price_4..."
            ],
            "currency": "$",
            "price": 30,
            "frequency": "week",
            "description": [
                "50 users included",
                "30 GB of storage",
                "Help center access",
                "Phone & email support"
            ],
            "free": false,
            "legacy": false
        },
        {
            "id": "legcy",
            "title": "Gold",
            "popular": true,
            "priceIds": [
                "price_2..."
            ],
            "currency": "$",
            "price": 10,
            "frequency": "week",
            "description": [
                "20 users included",
                "10 GB of storage",
                "Help center access",
                "Priority email support"
            ],
            "free": false,
            "legacy": true
        }
    ],
    "permissions": {
        "access": {
            "default": true,
            "admin": false
        },
        "admin": {
            "default": false,
            "admin": true
        }
    },
    "mailgun": {
        "api_key": "...",
        "domain": "app.mydomain.com",
        "from": "No Reply <[email protected]>",
        "templates":{
            "invite_email": "invite"
        }
    }
}

Setup Mailgun Integration (optional)

The framework integrates with Mailgun to send invite emails when users are invited to join subscription accounts. To setup the integration, retrieve the API key from Mailgun and create a file called mailgun.json under the src folder as the example below shows.

{
    "api_key": "...",
    "domain": "app.mydomain.com",
    "from": "No Reply <[email protected]>",
    "templates":{
        "invite_email": "invite"
}

In Mailgun, you will need a template for the invite emails. Create a template called invite with the subject line below.

{{sender}} invited you to {{site_name}}

In the template body, use the following copy.

Hi {{name}},

You received this invite because {{sender}} invited you to join {{site_name}}. Please sign in ({{sign_in_url}}) to accept the invite.

If you don't have a user account yet, please sign up ({{sign_up_url}}) here.

Best regards,

The {{site_name}} team

The invite template supports the following variables:

  • {{sender}} - the name of the person who sends the invite
  • {{site_name}} - the name of your web application defined in the cloud function configurations
  • {{name}} - the name of the new user who is invited by the sender
  • {{sign_in_url}} - the URL to the sign-in page which is defined in the cloud function configurations
  • {{sign_up_url}} - the URL to the sign-up page which is defined in the cloud function configurations

Note: The invite email is optional for the invite process. You can skip this step but the new users will need to be informed by other methods so that they know where to sign up and sign in to accept the invites.

Update Firestore Rules

The SaaS package uses Firestore database to store and manage the subscription data. To secure the data, the following Firestore rules need to be added to your Firestore database rules.

match /users/{userId}/paymentMethods/{paymentMethodId} {
    allow read, update, create, delete: if request.auth.uid == userId;
}
match /subscriptions/{subscriptionId} {
    allow read: if request.auth.uid != null && request.auth.uid in resource.data.permissions.access;
    allow update: if request.auth.uid != null && request.auth.uid in resource.data.permissions.admin && (!request.resource.data.diff(resource.data).affectedKeys()
        .hasAny(['currency', 'ownerId', 'paymentCycle', 'paymentMethod', 'plan', 'price', 'stripeItems', 'stripeSubscriptionId', 'subscriptionCreated', 'subscriptionCurrentPeriodEnd', 'subscriptionCurrentPeriodStart', 'subscriptionEnded', 'subscriptionStatus']));
}
match /subscriptions/{subscriptionId}/invoices/{invoiceId} {
    allow read: if request.auth.uid != null && request.auth.uid in get(/databases/$(database)/documents/subscriptions/$(subscriptionId)).data.permissions.admin;
}
match /invites/{inviteId} {
    allow read, delete: if request.auth.uid != null && request.auth.token.email == resource.data.email;
}

Modify /src/App.js

Replace the code in your src/App.js with the code below.

import './App.css';
import firebaseConfig from "./firebaseConfig.json";
import { pathnames, AppTemplate, AuthProvider, AuthRoutes, MainMenu, PublicTemplate, ResetPassword, SignIn, SignUp, UserMenu, UserProfile, UserUpdateEmail, UserUpdateName, UserUpdatePassword, UserDelete, FireactProvider, ActionPages } from '@fireactjs/core';
import { BrowserRouter, Routes } from "react-router-dom";
import { Route } from "react-router-dom";
import LocalFireDepartmentIcon from '@mui/icons-material/LocalFireDepartment';
import { CircularProgress, Box } from '@mui/material';
import authMethods from "./authMethods.json";
import { CreateSubscription, ListSubscriptions, pathnames as subPathnames, PermissionRouter, Settings, SubscriptionMenu, ListUsers, SubscriptionProvider, ListInvoices, ManagePaymentMethods, ChangePlan, CancelSubscription } from '@fireactjs/saas';
import SaaSConfig from './config.json';

const Brand = "FIREACT";

const Logo = ({size, color}) => {
	const logoColor = color || 'warning';
	return (
		<LocalFireDepartmentIcon color={logoColor} fontSize={size} />
	);
}

const Loader = ({size}) => {
	let cpSize = "35px";
	switch(size){
		case "small":
			cpSize = "30px";
			break;
		case "medium":
			cpSize = "35px";
			break;
		case "large":
			cpSize = "45px";
			break;
		default:
			cpSize = "35px";
			break;
	}
	return (
		<Box sx={{ display: 'flex', justifyContent: "center", alignItems: "center"}}>
			<CircularProgress color="warning" size={cpSize} />
			<div style={{position: "absolute" }}>
				<Logo size={size} />
			</div>
		</Box>
	);
}

function App() {

	// merge pathnames
	for(var key in subPathnames){
		pathnames[key] = subPathnames[key];
	}

	const config = {
		firebaseConfig: firebaseConfig,
		brand: "FIREACTJS",
		pathnames: pathnames,
		authProviders: authMethods,
		saas: SaaSConfig
	}

	return (
		<FireactProvider config={config}>
			<AuthProvider firebaseConfig={firebaseConfig} brand={Brand}>
				<BrowserRouter>
					<Routes>
						<Route element={<AuthRoutes loader={<Loader size="large" />} />} >
							<Route element={<AppTemplate logo={<Logo size="large" />} toolBarMenu={<UserMenu />} drawerMenu={<MainMenu />} />}>
								<Route exact path={pathnames.ListSubscriptions} element={<ListSubscriptions loader={<Loader size="large" />} />} />
								<Route exact path={pathnames.CreateSubscription} element={<CreateSubscription />} />
								<Route exact path={pathnames.UserProfile} element={<UserProfile />} />
								<Route exact path={pathnames.UserUpdateEmail} element={<UserUpdateEmail />} />
								<Route exact path={pathnames.UserUpdateName} element={<UserUpdateName />} />
								<Route exact path={pathnames.UserUpdatePassword} element={<UserUpdatePassword />} />
								<Route exact path={pathnames.UserDelete} element={<UserDelete />} />
							</Route>
							
							<Route path={pathnames.Subscription} element={<SubscriptionProvider loader={<Loader size="large" />} />} >
								<Route element={<AppTemplate logo={<Logo size="large" />} toolBarMenu={<UserMenu />} drawerMenu={<SubscriptionMenu />} />}>
									<Route element={<PermissionRouter permissions={["access"]} />} >
										<Route exact path={pathnames.Subscription+"/"} element={<div>Home</div>} />
									</Route>
									<Route element={<PermissionRouter permissions={["admin"]} />} >
										<Route exact path={pathnames.Settings} element={<Settings loader={<Loader size="large" />} />} />
										<Route exact path={pathnames.ListUsers} element={<ListUsers loader={<Loader size="large" />} />} />
										<Route exact path={pathnames.ListInvoices} element={<ListInvoices loader={<Loader size="large" />} />} />
										<Route exact path={pathnames.ManagePaymentMethods} element={<ManagePaymentMethods loader={<Loader size="large" />} />} />
										<Route exact path={pathnames.ChangePlan} element={<ChangePlan />} />
										<Route exact path={pathnames.CancelSubscription} element={<CancelSubscription />} />
									</Route>
								</Route>
							</Route>
						</Route>
						<Route element={<PublicTemplate />}>
							<Route path={pathnames.SignIn} element={
								<SignIn
									logo={<Logo size="large" />}
								/>
							} />
							<Route path={pathnames.SignUp} element={
								<SignUp
									logo={<Logo size="large" />}
								/>
							} />
							<Route path={pathnames.ResetPassword} element={
								<ResetPassword
									logo={<Logo size="large" />}
								/>
							} />
							<Route path={pathnames.ActionPages} element={
								<ActionPages
									logo={<Logo size="large" />}
								/>
							} />
						</Route>
					</Routes>
				</BrowserRouter>
			</AuthProvider>
		</FireactProvider>
	)
}

export default App;

Modify /functions/index.js

Replace the code in your /functions/index.js with the following code.

const admin = require('firebase-admin');
admin.initializeApp();
const config = require('./config.json');
let fireactjsSaasFunctions =  require('@fireactjs/saas-cloud-functions')(config);
exports.fireactjsSaas = fireactjsSaasFunctions;

Run your app locally

By now, your app is ready for the first run locally. Use the command npm start to start the app.

Deploy to Firebase

After testing locally, your app is ready to be deployed to Firebase hosting.

Build

Run npm run build to build your app

Deploy

Run firebase deploy to deploy your app to Firebase. If you see a blank screen in your production URL, make sure you set the build as the folder in your Firebase settings.

saas's People

Contributors

chaoming avatar nyan-left avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

saas's Issues

Theming

Hi,

I think I visited the demo several days ago and it looked like this
image

And now there is a material theme. How is it possible to change the theme back? As for me, the material theme looks worse and the previous one was much better for fast deployment. Or maybe you can help with some links how to change themes of MUI and where to search for nice themes? I am just not a web developer.

Thanks for the great work!
Dmitry

Plans are not ordered by price

Hi,

When you have plans with multiple prices, the order in which they're displayed can get messy.

I propose this is solved by ascent ordering them

See PR #5 :)

Initialization error

The default Firebase app does not exist. Make sure you call initializeApp() before using any of the Firebase services.

Screenshot 2023-04-05 at 10 55 08

Anyone using an M1 Mac to build/deploy?

Hello. This product looks great to save time on what I'm attempting to build. It's also my first React project, so sorry if these are common issues.

I'm working with an M1 iMac and I can't 'build install' without errors. Doing things one at a time, it looks like it's the Stripe stuff causing problems. I've tried installing node via brew both native and using Rosetta and I've even tried running the npm commands via Rosetta. I can attach the error messages if it'll help (once I get back to that machine). I'm just curious if anyone else here is working with an M1 Mac and had problems and how you got around them. I can get to an Intel Mac later today I can try on, but I'd love to be able to work on the iMac if possible. Thanks.

I get this when 'npm i @fireactjs/saas-cloud-functions'

npm audit fix --force
npm WARN using --force Recommended protections disabled.
npm WARN audit No fix available for react-scripts@>=2.1.4
npm WARN audit Updating @fireactjs/saas to 1.2.0, which is a SemVer major change.
npm WARN audit No fix available for @fireactjs/core@*
npm WARN audit No fix available for @fireactjs/saas-cloud-functions@*

removed 4 packages, changed 1 package, and audited 1836 packages in 7s

npm audit report

degenerator <3.0.1
Severity: high
Code Injection in pac-resolver - GHSA-9j49-mfvp-vmhm
No fix available
node_modules/degenerator
pac-resolver <=4.2.0
Depends on vulnerable versions of degenerator
Depends on vulnerable versions of netmask
node_modules/pac-resolver
pac-proxy-agent <=4.1.0
Depends on vulnerable versions of pac-resolver
node_modules/pac-proxy-agent
proxy-agent 1.1.0 - 4.0.1
Depends on vulnerable versions of pac-proxy-agent
node_modules/proxy-agent
mailgun-js >=0.6.8
Depends on vulnerable versions of proxy-agent
node_modules/mailgun-js
@fireactjs/saas-cloud-functions *
Depends on vulnerable versions of mailgun-js
node_modules/@fireactjs/saas-cloud-functions

netmask <=2.0.0
Severity: critical
Improper parsing of octal bytes in netmask - GHSA-4c7m-wxvm-r7gc
netmask npm package mishandles octal input data - GHSA-pch5-whg9-qr2r
No fix available
node_modules/netmask

nth-check <2.0.1
Severity: high
Inefficient Regular Expression Complexity in nth-check - GHSA-rp65-9cf3-cjxr
No fix available
node_modules/svgo/node_modules/nth-check
css-select <=3.1.0
Depends on vulnerable versions of nth-check
node_modules/svgo/node_modules/css-select
svgo 1.0.0 - 1.3.2
Depends on vulnerable versions of css-select
node_modules/svgo
@svgr/plugin-svgo <=5.5.0
Depends on vulnerable versions of svgo
node_modules/@svgr/plugin-svgo
@svgr/webpack 4.0.0 - 5.5.0
Depends on vulnerable versions of @svgr/plugin-svgo
node_modules/@svgr/webpack
react-scripts >=2.1.4
Depends on vulnerable versions of @svgr/webpack
Depends on vulnerable versions of resolve-url-loader
node_modules/react-scripts
@fireactjs/core *
Depends on vulnerable versions of react-scripts
node_modules/@fireactjs/core
@fireactjs/saas *
Depends on vulnerable versions of @fireactjs/core
Depends on vulnerable versions of react-scripts
node_modules/@fireactjs/saas

postcss <8.4.31
Severity: moderate
PostCSS line return parsing error - GHSA-7fh5-64p2-3v2j
No fix available
node_modules/resolve-url-loader/node_modules/postcss
resolve-url-loader 0.0.1-experiment-postcss || 3.0.0-alpha.1 - 4.0.0
Depends on vulnerable versions of postcss
node_modules/resolve-url-loader

17 vulnerabilities (4 moderate, 12 high, 1 critical)

Some issues need review, and may require choosing
a different dependency.

Why adminRefs?

Hi Chaoming Li, thanks for this amazing starter template. I am new to web dev so this has been much of help.

I just wanted to ask that why do we need "adminRefs" in our database? Like we already have the "admin" array to check if user has the permissions.

No window.coreui object in browser when run locally

For some reason, when running locally (using npm run start), the javascript for coreui (called from the <script> element in public/index.html) doesn't appear to be running, so there's no window.coreui object available in my console (so I'm throwing an error when trying to call Sidebar._sidebarInterface(element) in src/components/menus/AppMenu/index.js:8, see image attached). The hosted version on firebase works perfectly, however. Any idea why I wouldn't be able to load the coreui javascript locally or how to solve this?
Ps. very cool project, thanks for putting it together!
image

How do you determine if a user has a subscription?

First - Amazing project. You saved me like 2 weeks of development with this boilerplate. Installed in 10 minutes and worked perfectly first try.

Is there a function in the boilerplate thats used to check if a user is subscribed so I can implement paywalled content? i.e. hasActiveSubscription()?

Cypress E2E tests

Hi @chaoming ,

I would like to contribute to this project by adding Cypress tests, how can I proceed with it?

Thanks.

How to add credit card details with name and address?

Hi Chaoming Li,

Thanks a lot for the Fireact project. It saves lot of time in implementing e2e SaaS app. One question, while selecting subscription and make credit card payment, it asks only credit card number, but I need to also show name and address also as shown in the attachment. Is it possible to include this change in fireact?.

credit card details

No session create?

Per documentation:

Note that we require Stripe.js for all applications—you won't be allowed to send credit card data directly from your server.

How are you able to pass the details directly? Shouldn't you create a token with Stripe Checkout or Stripe.js first?

404 not found when refreshing page

Hi, thanks for a great repo!

I managed to deploy it to firebase hosting following your documentation. However, there is an issue in the deployed website, which does not reproduce locally or at your demo page.

So https://demo.fireact.dev/ get's redirected to https://demo.fireact.dev/signin?re=/ and if you then press F5, the page will reload well to the same as before reloading.

If I do npm run start locally and do the same on localhost -- also works without problems.

Once I do firebase deploy and try it on the hosted website -- F5 turns into 404. You can try it here: [deleted link] . Can you please help fixing this?

Issue with deployment

I followed all the steps in the documentation. I get following screen (as well if I run the project locally)

image

Any idea?

How to test following cloud functions?

Hi,

How to test following cloud functions?.

acceptInvite
getInvite
inviteEmailToAccount

I added new users (mix of "admin" and "user") to an account, but not sure how to test above scenario.

Stuck

After following all the steps, i got a welcome screen (changed the public directory to 'build')
Screenshot 2023-03-18 at 4 15 58 PM

Any help please?

coreui error

Hi,

Since this morning , getting this error, how to fix it?..

core ui error

Billing period on invoice doesn't show monthly term length

Hi, having a monthly subscription in stripe (as setup via your documentation) the invoice billing period doesn't show the entire month of the subscription. Is this a bug or is it supposed to show this?

...
Created Time:
5/4/2021, 3:28:06 PM
Billing Period:
5/4/2021, 3:28:06 PM ~ 5/4/2021, 3:28:06 PM
....

mailgun configuration

I have setup custom domain in Mailgun .and it is working fine in Postman.
But if I use the same configuration in the mailgun.json, and testing the user invite function, it is not working.
Is there any other parameter should i add in the mailgun.json file?

"api_key": "<my private api key",
"domain": "https://api.mailgun.net/v3/my custom domain/messages",
"site_name": "my custom domain",
"from": "mailgun@my custom domain",
"invite_url": "https://my custom domain/invite"

Blank page when hosted on Firebase

Hi Chaoming! First of all thanks for the generosity with this effort!

I've been trying to make this work but when it's hosted up on Firebase I just see a blank page, even though the deployment ends successfully. When I open it in localhost everything works as expected. I'm afraid there might be something wrong in my firebase.json file, as there's none in your repo that I can reference. Would it make sense to add it to the repo so we check? Here's my version of it:

{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "functions": {
    "predeploy": [
      "npm --prefix \"$RESOURCE_DIR\" run lint"
    ],
    "source": "functions"
  },
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

There might be something very obvious I'm missing as I'm new to React.

Thanks again!

cannot run the code locally

image
image
image

WARNING in ./node_modules/@firebase/webchannel-wrapper/dist/index.js
Module Warning (from ./node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from 'F:\proj2022\chatgpt_toB\saas\node_modules@firebase\webchannel-wrapper\dist\src\com\google\javascript\jscomp\js\util\owns.js' file: Error: ENOENT: no such file or directory, open 'F:\proj2022\chatgpt_toB\saas\node_modules@firebase\webchannel-wrapper\dist\src\com\google\javascript\jscomp\js\util\owns.js'

WARNING in ./node_modules/@firebase/webchannel-wrapper/dist/index.js
Module Warning (from ./node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from 'F:\proj2022\chatgpt_toB\saas\node_modules@firebase\webchannel-wrapper\dist\src\com\google\javascript\jscomp\js\util\polyfill.js' file: Error: ENOENT: no such file or directory, open 'F:\proj2022\chatgpt_toB\saas\node_modules@firebase\webchannel-wrapper\dist\src\com\google\javascript\jscomp\js\util\polyfill.js'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.