search
HomeWeb Front-endJS TutorialNgSysV.Creating a simple Svelte Information System with Google&#s Firestore

This post series is indexed at NgateSystems.com. You'll find a super-useful keyword search facility there too.

Last reviewed: Nov '24

1. Introduction

Most webapps exist purely to create and access shared information. Consider, Amazon's https://www.amazon.co.uk/ website. The essential purpose of this system is to let you browse a central collection of product details, place orders and monitor progress on delivery. To make this work, Amazon must:

  • Maintain this information somewhere accessible over the web
  • Structure and manage it to ensure near-instant access and total integrity.

This post is all about the "database" technology used to achieve these aims.

Warning - this is a long post because database reads and writes in Svelte draw you remorselessly into using SvelteKit's client-server architecture. Previously, your code ran exclusively "client-side" in your web browser. Now you'll also be running code on the local server launched by npm run dev. This has consequences...

I've looked at ways of splitting the post up but they don't work. To make matters worse, the Javascript you'll use contains many new features. So, I'm sorry - you're just going to have to suck it up.

But look on the bright side. Once you're through this, things will start to get easier. Take it slowly. Use chatGPT where you feel I've not explained something clearly. You'll find the bot particularly helpful when you need advice on JavaScript syntax. Relax. This is going to be fun!

2. Configuring your project to use Google's Firestore

There are innumerable ways of storing shared data on the web. This post series uses Google's Firestore system because it suits beginners. It requires minimal setup and fits comfortably within the structure of a Svelte webapp.

You'll need to perform four initial steps:

  1. Obtain a Google account
  2. Create a Firebase project under this account
  3. Register your "webapp"
  4. Initialise a Firestore Database for your Firebase project

Firebase is Google's umbrella term for many different services you might use to mount a simple project on the web. The services for a given account are managed via Google's "Firebase console" at https://console.firebase.google.com/. They include both a "Storage" service that enables you to upload files into the Google Cloud and a "Firestore Database" service. A database differs from a file in that it possesses a configurable structure. It enables you to access and update discrete elements of the configured data set.

2.1 Obtaining a Google account

If you have a Gmail address, you're already covered because this automatically counts as a Google account. If you don't, follow the instructions at Create a Google Account to get one.

2.2 Creating a Firebase project for your code

Launch the Google Firebase console and log in with your Google Account (noting that, if you're logged into Gmail with this, you're already logged into the Firebase Console as well). Now click the "Create a Project" box to launch the process.

Google will want you to supply a name for your project (I suggest you use the project name you're using in VSCode), and will propose an extension that makes this a unique "Project Identifier" within the Firebase world. So for, example, my version of the "Svelte-dev" project used in this post series is known to Google as "Svelte-dev-afbaf".

As an aside, since the Project Identifier will ultimately form part of the default live URL for your webapp, and since Google lets you edit its initial "uniqueness extension" proposal, you might be tempted to try to change this to something meaningful. However, I suggest you forget this idea. Firstly, you'll find it difficult to pick an identifier that suits both parties. Secondly, in my experience, these "default URLs" aren't ever indexed by Google. A "custom URL" purchased at minimal cost and linked to your default URL when you go live is by far the best way to get a memorable URL.

Now click "Continue" to reveal a "Google Analytics" registration page. You can safely ignore this here as it is relevant only to performance issues on live apps. Use the slider bar to decline it and click the "Create Project" button to continue.

The lights now dim a little as Google registers your project. Finally, once you've clicked one more "Continue" button, you'll find yourself in your project's Firebase Console window. Here's a screenshot of the Firestore tab for a "svelte-dev" project:

NgSysV.Creating a simple Svelte Information System with Google

It's worth giving yourself a moment to familiarise yourself with this page because it is a little complicated. The basic structure consists of a "tools menu" on the left that determines what gets displayed in the main panel on the right. The problem is that the menu is "adaptive" and maintains a "Project shortcuts" section that remembers where you've been. Consequently, the menu seems to look different every time you open the console! Once you've grasped this feature, however, things work well. Note that the complete set of tools is hidden within the "Build", "Run" and "Analytics" submenus of their parent "Product Categories" menu item. The "Build" set contains everything you need at present.

Before you proceed further, note the following:

  • information at the top of the screen confirms that the svelte-test project is currently registered on the "Spark" plan. This means that everything you're doing at present is free. Eventually, in this post series, you will get to a point where you need to start to paying Google, and will need to upgrade your project to the "Blaze" tariff. But don't worry - this is a long way off yet, you won't pay much, and you can create a monthy budget to limit the amount Google might try to charge you.
  • project details are revealed by clicking the "Project Overview" button at the top of the toolbar. Details available here include a reminder of the Project Identifier and a button to delete the project. If everything goes wrong, you can always use this to rub out the mess and start over again. This won't cost you anything

2.3 Registering your webapp

Firebase needs to know what your webapp will be called:

  • Click the > icon below the "Get started" message and supply a nickname when requested. I suggest you use your project name again here (eg "svelte-dev").
  • Ignore the offer to "Set up Firebase Hosting for this app" because, when we finally get around to deployment, all your hosting needs will be handled by App Engine.
  • Finally, click "Register" and "Continue to the console" to return to the initial console screen.

2.4 - Initialising a Firestore database

Select "Firestore Database" from the "Build" stack in the tools menu to obtain the Firebase console view shown below:

NgSysV.Creating a simple Svelte Information System with Google

Once you've clicked the "Create Database" button, the console will want you to:

  1. Set your database "Name and Location". "Name" is the identifier for the database and will only be relevant if you plan to create several different databases in your project. Leave this empty, for now, so that Google uses its "default" setting. "Location" specifies where your database will be physically located. The pull-down list of options available here is possibly your first sight of the scale of the Google Cloud service. Its server farms are available right around the globe. You will probably want to select a server close to your location. For example, I generally use "europe-west2 : Heathrow" since I am based in the UK. Pages elsewhere in the Google Cloud console enable you to specify performance and availability characteristics, but you don't need to look at these for now.

  2. Secure your database with "Rules". The screen here offers you a choice between setting initial "production" and "test" "rules". This only makes sense, of course, if you know what "rules" are in the first place - and this isn't the right time for me to explain them. Unless you know better, I'd like you to check the "test mode" option here. Be assured, I'll come back to this later when I talk about "authorisation" (and, oh boy, is there a lot to talk about!).

Once you're through these two stages, the Cloud Firestore page opens in the Firebase Console. What now?

3. Working with a Firestore Database

This section aims to answer the following questions:

  1. What is a database?
  2. What does a Firestore database look like?
  3. How can I initialise a database in the Firestore console?
  4. How can I access a Firestore database in Javascript?
  5. How can I get a Svelte page.svelte file to load data from a Firestore database?
  6. How can I get a Svelte page.svelte file to add data to a Firestore database?

3.1 What is a database?

For our immediate purposes, a database is a set of tables containing rows of values for named data "fields". So, for example, a Customer Order" database might contain

  • a "Customers" table full of "Customer Id" and "Customer Address Details" field values
  • a "Products" table full of "Product Number" and "Product Detail" fields
  • a "Customer Orders" table with details of the orders for a "Product Number" placed by a "Customer Id"

The important thing is that such an arrangement is structured with consistent standards for the naming and formatting of data content

3.2 What does a Firestore database look like?

In Firestore, tables are called "collections" and rows within them are called "documents". Documents stored within a collection aren't all required to have the same fields, but field names and content are expected to follow consistent patterns throughout the collection.

An important feature of a Firestore document is that it should have a unique identifier or "key". Sometimes there will be a field such as "Email Address" within each document that you can use to provide a "natural" unique key. If not, Firestore can be asked to create an artificial key automatically.

Database design is probably the most challenging part of system development and, once again, I will duck this because the issues involved will only become clear when you've had some practical experience. However, when you have a moment, you will find it useful to check out the Cloud Firestore Data model page.

3.3 How can I initialise a database in the Firestore console?

In this post, I plan to show you how to create a single products collection in your default Firestore database. This will contain simple documents containing a product number field with a key automatically generated by Firestore.

On the Firestore page on the Firebase console, click the "Start collection" button and enter the name "products" in the "Collection ID" field of the popup that now appears.

NgSysV.Creating a simple Svelte Information System with Google

Now use the data entry page to create a test products document containing a "productNumber" field with a numeric value of "1" and a "productDetails" field with a text value of "Product 1".

  • Type "productNumber" in the "Field" entry box to set the field name, set the "Type" box to "number" and enter "1" (without the quote characters) in the "Value" box.
  • Click "add field and type "productDetails" in the "Field" entry box to set the field name, leave the "Type" box set to its default "string" setting and enter "Product 1" (without the quote characters) in the "Value" box.

Now sign off the document by first clicking the "Auto Id" button and then "Saving" it Here's what the console should look like now:

NgSysV.Creating a simple Svelte Information System with Google

If you wanted to add further documents, you would click "add document" at this point, but that's not necessary in this case - you only need a single document to demonstrate your webapp's ability to read it.

You're finished here for now, but note that the console's "panel view" lets you edit or delete the document you've just created. If you've got in a complete mess you can even delete the entire collection and start again.

3.4 How can I access a Firestore database in Javascript?

Here's where things start to get really interesting!

Google provides a library of Javascript functions to let you read and write Firestore documents. Such libraries are referred to as "APIs" (Application Program Interfaces). Have a look at the following code that shows how the firebase/firestore library would be used to read all the documents in svelte-dev's products collection:

import { collection, query, getDocs, orderBy } from "firebase/firestore";
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

const firebaseConfig = {
    apiKey: "AIzaSyCE933 ... klfhFdwQg1IF1pWaR1iE",
    authDomain: "svelte-dev-afbaf.firebaseapp.com",
    projectId: "svelte-dev-afbaf",
    storageBucket: "svelte-devt-afbaf.appspot.com",
    messagingSenderId: "1027 ... 85697",
    appId: "1:1027546585697:web:27002bf ..... b0f088e820",
};

const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);

const productsCollRef = collection(db, "products");
const productsQuery = query(productsCollRef, orderBy("productNumber", "asc"));
const productsSnapshot = await getDocs(productsQuery);

let currentProducts = [];

productsSnapshot.forEach((product) => {
    currentProducts.push({productNumber: product.data().productNumber});
});

return { products: currentProducts } // accessed in +page.svelte as data.products

Concentrate on the section that starts const productsCollRef = collection(db, "products");. This uses Firestore API calls to load a sorted copy of all documents within the products collection into the State currentProducts variable.

First, the collection and query functions, drawn from the Firestore Client API library, are used to point Firebase at the products collection and define a query to run on it. Then the query is launched by a getDocs API call.

I won't attempt to describe the mechanics of this sequence of Firestore API calls. Treat these as a piece of "boiler-plate code" - code - the sort of thing that you write once and, ever afterwards, simply copy. Since you'll find you need a whole library of templates to cover the full array of Firestore "read", "update" and "delete" operations, you might find it useful to look at Post 10.1 - Firestore CRUD command templates. If you'd like to check out Google's own description of the API, you'll find links to these at the end of Post 10.1.

"CRUD" here is short for "create", "read", "update" and "delete".

The getDocs result is returned as an array of documents conventionally called a "snapshot". However, note that the getDocs function call is preceded by an await keyword.

The await keyword is needed here because, by default in Javascript, instructions referencing external data sources that may take an unpredictable time to complete are handled asynchronously. The "await" keyword essentially (though this is a gross simplification) enables you to override this arrangement. When you have more time, you might find it useful to have a look at A simple guide to the Javascript fetch() API and the "await" keyword

But right now, returning to our code snippet above, look at the section starting with the const firebaseConfig statement.

The firebaseConfig declaration initialises an object containing the configuration details needed to connect your web app to your specific Firebase project. It includes various keys and identifiers that Firebase uses to locate and authenticate your app. You'll find the settings for your particular webapp in "Project Overview/Project settings" on the Firebase console. The firebaseConfig settings in the code samples below have been "obfuscated" because they are unique to my project and aren't to be passed around lightly (more about this shortly). When trying the sample code below, you'll need to copy in the firebaseConfig settings from your own project.

With firebaseConfig initialised, the webapp can initialise the db variable required by the query's const productsCollRef = collection(db, "products"); statement:

import { collection, query, getDocs, orderBy } from "firebase/firestore";
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

const firebaseConfig = {
    apiKey: "AIzaSyCE933 ... klfhFdwQg1IF1pWaR1iE",
    authDomain: "svelte-dev-afbaf.firebaseapp.com",
    projectId: "svelte-dev-afbaf",
    storageBucket: "svelte-devt-afbaf.appspot.com",
    messagingSenderId: "1027 ... 85697",
    appId: "1:1027546585697:web:27002bf ..... b0f088e820",
};

const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);

const productsCollRef = collection(db, "products");
const productsQuery = query(productsCollRef, orderBy("productNumber", "asc"));
const productsSnapshot = await getDocs(productsQuery);

let currentProducts = [];

productsSnapshot.forEach((product) => {
    currentProducts.push({productNumber: product.data().productNumber});
});

return { products: currentProducts } // accessed in +page.svelte as data.products

Finally, you may be wondering where these API functions come from. The answer is that they are imported from locations in your project by the three statements at the top of the code block:

const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);

Here "modular libraries" are being accessed to supply functions for your code. Named functions such as collection are extracted from a parent module to fulfil the references required later in the code.

But then this leads to the question "And how do modular libraries get into my project in the first place?" The answer, of course, is that you have to put them there, and the tool you use to do this is faithful old npm.

Back in a VSCode svelte-test terminal session (terminate the dev server if necessary with a couple of ctrl-C keystrokes) and run the following instruction'

import { collection, query, getDocs, orderBy } from "firebase/firestore";
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

const firebaseConfig = {
    apiKey: "AIzaSyCE933 ... klfhFdwQg1IF1pWaR1iE",
    authDomain: "svelte-dev-afbaf.firebaseapp.com",
    projectId: "svelte-dev-afbaf",
    storageBucket: "svelte-devt-afbaf.appspot.com",
    messagingSenderId: "1027 ... 85697",
    appId: "1:1027546585697:web:27002bf ..... b0f088e820",
};

const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);

const productsCollRef = collection(db, "products");
const productsQuery = query(productsCollRef, orderBy("productNumber", "asc"));
const productsSnapshot = await getDocs(productsQuery);

let currentProducts = [];

productsSnapshot.forEach((product) => {
    currentProducts.push({productNumber: product.data().productNumber});
});

return { products: currentProducts } // accessed in +page.svelte as data.products

After a minute or two (the installation involves a sizeable download), you'll be poised to run code that downloads a Firestore database collection. But, you still don't know how to embed this in a Svelte webapp. So, on to the next question...

3.5 How can I get a Svelte page.svelte file to load data from a Firestore database?

This has been a long haul but, hang in there, you're nearly finished.

Currently, in the <script> section of your src/routes/ page.svelte file, you have the following statement:<br> </script>

const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);

As you know, this declares your products field as a State variable and initialises it as an empty array. What you want to do now is replace "empty" with the content of the products Firestore collection.

Unfortunately, as you've seen, this involves an asynchronous operation. This complicates things somewhat because Svelte doesn't want anything to slow down the initial load of a page - it's happy to see information added later but, the first user impression should be of an instantaneous response. Svelte has a standard arrangement for loading initial data into a page.svelte file. It goes like this:

First, you create a new src/routes/ page.server.js file that wraps all your asynchronous code inside a load() function (mandatory name) and returns its results as an object.

Here's the code

import { collection, query, getDocs, orderBy } from "firebase/firestore";
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

The load function above returns an object with a single products property whose value is the currentProducts array constructed by the Firestore API calls.

This is all very well, but how is this to be conveyed to the products state variable in page.svelte?

The first step is to advertise a new data (mandatory name) state variable as a prop (short for "property") of page.svelteYou do this by declaring it with an export keyword, thus:

npm install firebase

Props won't be covered in this series until you get to Post 3.1 in this series and learn about "components". For now, think of your page.svelte file as a function with data as its parameter.

When you run your page.svelte file now, the SvelteKit framework sees the export let data declaration with its reserved data keyword and thinks, "ah, I need to run the load() function associated with this page". The products data is duly returned into the data prop of page.svelte and now, since this is a reactive variable, the page is refreshed.

All you need to do to make your existing "template" code work with the new arrangement is to replace products references with data.products

The page.server.js file is your first sight of "server-side" code in Svelte - that is, code that runs in the server. All the page.svelte code you've seen so far runs "client-side" in the browser. A page.server.js file, by contrast, runs either in the local server launched by npm run dev or, after deployment, in the Node.js environment of an App Engine server. Server-side code runs faster than client-side code and is secure. The only person who can view or change it is you - its owner.

Here's the complete code for a modified version of the page.svelte file from Post 2.2:

import { collection, query, getDocs, orderBy } from "firebase/firestore";
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

const firebaseConfig = {
    apiKey: "AIzaSyCE933 ... klfhFdwQg1IF1pWaR1iE",
    authDomain: "svelte-dev-afbaf.firebaseapp.com",
    projectId: "svelte-dev-afbaf",
    storageBucket: "svelte-devt-afbaf.appspot.com",
    messagingSenderId: "1027 ... 85697",
    appId: "1:1027546585697:web:27002bf ..... b0f088e820",
};

const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);

const productsCollRef = collection(db, "products");
const productsQuery = query(productsCollRef, orderBy("productNumber", "asc"));
const productsSnapshot = await getDocs(productsQuery);

let currentProducts = [];

productsSnapshot.forEach((product) => {
    currentProducts.push({productNumber: product.data().productNumber});
});

return { products: currentProducts } // accessed in +page.svelte as data.products

Where should this code be located? Currently, the code fired by the "Add Another Product"

's on:click button lives in your page.svelte file. But Svelte advises that, for security and efficiency reasons, the database update should be performed "server-side" in page.server.js in an actions() function paralleling the load() function you've already created here. The function is triggered by "posting" data from the
.

Here's what the new

arrangement in page.svelte should look like:
const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);

The object returned by the "actions" function becomes available to the page.svelte file through the form prop declared in its <script> section. Here, an export let form; statement parallels the earlier use of a data prop to return the results of a load() function.</script>

Here are the complete versions of page.svelte and page.server.js:

import { collection, query, getDocs, orderBy } from "firebase/firestore";
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

If you copy this code, remember to reset the firestoreConfig data again. If you have problems getting it to work, remember also the advice in the previous post about debugging client-side code and look at the "Postscript sections" below for advice about fixing server-side problems. Good luck!

Note that the FireStore API imports and db configuration statements in page.server.js have been given "file scope" by moving them out of the functions they serve and relocating them at the top of the file's <script> section. In a more complex project, it would be common practice to configure db in a separate lib folder to enable it to be shared more widely as an import.</script>

You'll also note that the new code drops the resetting of the popupVisible field that previously appeared in the old page.svelte file's on:click function. Svelte's default action on form submission is to reload the page. Consequently, when the form has been processed, popupVisible is re-initialised as false, the "Currently-registered products:" array is refreshed from the updated Firestore products collection and the popup disappears. As a bonus, the new Product Number will be inserted in the correct sorted order, courtesy of the orderBy("productNumber", "asc") qualifier in the products getDocs.

Caveat: code like this will only work while your Firestore database is public. When you add rules to restrict a collection's access to authorised users (ie users who have "logged in"), the Firestore templates you've been using here will fail. Posts in the next section of this series will explain why and Post 3.4 in particular will explain how you can fall back to code based purely on client-side page.svelte files. However, since this will be at the expense of security and performance, I hope you'll fight your way through these "minor irritations" and continue developing client-server code. For the present, make sure that your database rules look something like:

import { collection, query, getDocs, orderBy } from "firebase/firestore";
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

const firebaseConfig = {
    apiKey: "AIzaSyCE933 ... klfhFdwQg1IF1pWaR1iE",
    authDomain: "svelte-dev-afbaf.firebaseapp.com",
    projectId: "svelte-dev-afbaf",
    storageBucket: "svelte-devt-afbaf.appspot.com",
    messagingSenderId: "1027 ... 85697",
    appId: "1:1027546585697:web:27002bf ..... b0f088e820",
};

const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);

const productsCollRef = collection(db, "products");
const productsQuery = query(productsCollRef, orderBy("productNumber", "asc"));
const productsSnapshot = await getDocs(productsQuery);

let currentProducts = [];

productsSnapshot.forEach((product) => {
    currentProducts.push({productNumber: product.data().productNumber});
});

return { products: currentProducts } // accessed in +page.svelte as data.products

4. Summary

I imagine that this post will have strained your patience to the limit. If you've reached this point with a working webapp and your sanity still intact, give yourself a gold star - you've covered most of the core Svelte topics and got a handle on the essential skills!

That said, there's still a lot to learn. For example, this post has ducked out of describing basic error handling, and form validation arrangements. Beyond that, I also want to introduce you to Svelte routes(ie pages), layouts (page headers and trailers), components, and the tricky issues surrounding security (login design and database rules). Finally, there's the interesting question of how you deploy your webapp for live operation on the web. I hope you'll read on!

Postcript: When things go wrong

The introduction of "server-side" processing in your webapp has fast-tracked you straight into the senior developer league. This is because the "Chrome Inspector" techniques that I hope you've enjoyed using on your page.svelte files don't work on page.server.js files. But all is not lost. Here's an introduction to the techniques that a senior developer would use:

Postscript (a): Debugging Server side code in the Terminal Session

Although the VSCode editor will do its best to help you produce sound code, some basic errors will only become apparent when the SvelteKit server tries to run your webapp. At this point, your screen may display a "500 - Internal Error" message (if it displays anything at all!). The browser can't help you much here because a page.server.js file is essentially invisible here. While the Source tab's Page/localhost storage hierarchy continues to show your page.svelte file, it has nothing to say about page.server.js.

But the Inspector knows that an error has occurred and can sometimes give you useful a clue as to its cause. The right-hand end of the menu bar will show a red icon with a cross in the middle. Click this and the Inspector's console will open and display summary error details. But if you need full details, you'll find these in the terminal session where you launched the server with npm run dev.

The problem here is that you'll likely feel the level of detail is probably rather too full. Every error is reported with a "call stack" that details the full sequence of server function calls that preceded the failure point Here's a short one precipitated by an incorrect field name declaration (I deliberately mistype const db= as const dba =

import { collection, query, getDocs, orderBy } from "firebase/firestore";
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

const firebaseConfig = {
    apiKey: "AIzaSyCE933 ... klfhFdwQg1IF1pWaR1iE",
    authDomain: "svelte-dev-afbaf.firebaseapp.com",
    projectId: "svelte-dev-afbaf",
    storageBucket: "svelte-devt-afbaf.appspot.com",
    messagingSenderId: "1027 ... 85697",
    appId: "1:1027546585697:web:27002bf ..... b0f088e820",
};

const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);

const productsCollRef = collection(db, "products");
const productsQuery = query(productsCollRef, orderBy("productNumber", "asc"));
const productsSnapshot = await getDocs(productsQuery);

let currentProducts = [];

productsSnapshot.forEach((product) => {
    currentProducts.push({productNumber: product.data().productNumber});
});

return { products: currentProducts } // accessed in +page.svelte as data.products

A terminal window isn't a good place to view information like this. Sometimes you have to scroll up or down to find what you want, and information may be additionally obscured by output from other activities. Nevertheless, it's all you've got so you need to make the best of it.

But note that, in the example shown above, the cause of the error is signalled very clearly - the server has encountered a reference to a db variable in page.server.js at line 18 column 38 and db hasn't been declared. That gives you everything you need, I think.

The terminal window can help you fix problems with your logic too. In the past, "debugging" was usually carried out by placing console.log messages messages at strategic points in the code and it's easy enough to use this approach here. A typical log message would be:

const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);

A log message like this placed in a page.server.js file will be displayed in the VSCode terminal window (by contrast, log statements in a client-side page.svelte code will continue to be displayed in the browser's console window).

Postscript (b): Debugging Server side code in the VSCode debugger

Console.log messages are fine for fixing minor issues, but by now you expect to be able to use something with the sophistication of the browser "breakpoint" debugging tool. Fear not. You can now find this in the VSCode. editor. Here's what you do:

  1. Open the page.server.js file you want to debug and set a breakpoint at a point you'd like to inspect. You do this by mousing over the source line you want to use as a breakpoint and clicking on the pale red dot that will appear at its left-hand side. The pale red dot now changes to bright red.
  2. In the VSCode command palette (shortcut "ctrl shift p") choose Debug: Attach to node process and get a list of projects in your workspace. Select the one you want to debug.
  3. Note that the terminal session that you've just launched is labelled as "Javascript Debug Terminal". Type 'npm run dev` into this terminal and note how the usual Vite output that appears includes an additional "Debugger attached" line. Note also how VSCode's activity bar has turned orange
  4. Now mouse over the http://localhost address displayed by Vite and launch the webapp with a "ctrl-click". Your webapp now opens in a popup window.
  5. You'll now find that the editor page for your page.server.js file has become an active debugging session with execution halted on the first breakpoint. A panel at the top of the editor window displays the familiar "advance to next breakpoint" etc buttons, and mousing over field names will reveal tooltips that display their values. As before, if a debug session is halted on a variable assignment statement, you'll only see the result of this when you advance to the next statement.
  6. Terminate the debug session by mousing over the icon at the far end of the debug controls panel. This toggles between "disconnect" and "stop" actions when you press the "alt" key. Click this when it displays "disconnect" and the orange VSCode activity bar will turn blue again. If you want to resume debugging, "ctrl click" on the webapp URL in the debugging terminal window again (which will stay active until you explicitly "bin" it)

The screenshot below shows the page.server.js file for this post halted on the return from the load() function. A "mouseover" on the products property for the return at this point displays the result of reading the Firestore products collection.

NgSysV.Creating a simple Svelte Information System with Google

For full details of the facilities available in the VSCode debugger, see the documentation at VSCode debugging

The above is the detailed content of NgSysV.Creating a simple Svelte Information System with Google&#s Firestore. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Python vs. JavaScript: Choosing the Right Tool for the JobPython vs. JavaScript: Choosing the Right Tool for the JobMay 08, 2025 am 12:10 AM

Whether to choose Python or JavaScript depends on the project type: 1) Choose Python for data science and automation tasks; 2) Choose JavaScript for front-end and full-stack development. Python is favored for its powerful library in data processing and automation, while JavaScript is indispensable for its advantages in web interaction and full-stack development.

Python and JavaScript: Understanding the Strengths of EachPython and JavaScript: Understanding the Strengths of EachMay 06, 2025 am 12:15 AM

Python and JavaScript each have their own advantages, and the choice depends on project needs and personal preferences. 1. Python is easy to learn, with concise syntax, suitable for data science and back-end development, but has a slow execution speed. 2. JavaScript is everywhere in front-end development and has strong asynchronous programming capabilities. Node.js makes it suitable for full-stack development, but the syntax may be complex and error-prone.

JavaScript's Core: Is It Built on C or C  ?JavaScript's Core: Is It Built on C or C ?May 05, 2025 am 12:07 AM

JavaScriptisnotbuiltonCorC ;it'saninterpretedlanguagethatrunsonenginesoftenwritteninC .1)JavaScriptwasdesignedasalightweight,interpretedlanguageforwebbrowsers.2)EnginesevolvedfromsimpleinterpreterstoJITcompilers,typicallyinC ,improvingperformance.

JavaScript Applications: From Front-End to Back-EndJavaScript Applications: From Front-End to Back-EndMay 04, 2025 am 12:12 AM

JavaScript can be used for front-end and back-end development. The front-end enhances the user experience through DOM operations, and the back-end handles server tasks through Node.js. 1. Front-end example: Change the content of the web page text. 2. Backend example: Create a Node.js server.

Python vs. JavaScript: Which Language Should You Learn?Python vs. JavaScript: Which Language Should You Learn?May 03, 2025 am 12:10 AM

Choosing Python or JavaScript should be based on career development, learning curve and ecosystem: 1) Career development: Python is suitable for data science and back-end development, while JavaScript is suitable for front-end and full-stack development. 2) Learning curve: Python syntax is concise and suitable for beginners; JavaScript syntax is flexible. 3) Ecosystem: Python has rich scientific computing libraries, and JavaScript has a powerful front-end framework.

JavaScript Frameworks: Powering Modern Web DevelopmentJavaScript Frameworks: Powering Modern Web DevelopmentMay 02, 2025 am 12:04 AM

The power of the JavaScript framework lies in simplifying development, improving user experience and application performance. When choosing a framework, consider: 1. Project size and complexity, 2. Team experience, 3. Ecosystem and community support.

The Relationship Between JavaScript, C  , and BrowsersThe Relationship Between JavaScript, C , and BrowsersMay 01, 2025 am 12:06 AM

Introduction I know you may find it strange, what exactly does JavaScript, C and browser have to do? They seem to be unrelated, but in fact, they play a very important role in modern web development. Today we will discuss the close connection between these three. Through this article, you will learn how JavaScript runs in the browser, the role of C in the browser engine, and how they work together to drive rendering and interaction of web pages. We all know the relationship between JavaScript and browser. JavaScript is the core language of front-end development. It runs directly in the browser, making web pages vivid and interesting. Have you ever wondered why JavaScr

Node.js Streams with TypeScriptNode.js Streams with TypeScriptApr 30, 2025 am 08:22 AM

Node.js excels at efficient I/O, largely thanks to streams. Streams process data incrementally, avoiding memory overload—ideal for large files, network tasks, and real-time applications. Combining streams with TypeScript's type safety creates a powe

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool