Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Documentation for Ionic #1

Merged
merged 4 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion docs/Troubleshooting/using-logs.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,44 @@ id: using-logs
sidebar_position: 1
---

# Using Logs
# Using Logs for Troubleshooting

> Description — _Couchbase Lite on Ionic — Using Logs for Troubleshooting_
> Related Content — [Troubleshooting Queries](troubeshoot-queries.md) | [Troubleshooting Crashes](troubleshoot-crashes.md)

:::note
* The retrieval of logs from the device is out of scope of this feature.
* This content applies to the post 2.5 versions. If you are using a Couchbase Lite release prior to 2.5 see Deprecated functionality.
:::

## Introduction

Couchbase Lite provides a robust Logging API — see: API References for Logging classes — which make debugging and troubleshooting easier during development and in production. It delivers flexibility in terms of how logs are generated and retained, whilst also maintaining the level of logging required by Couchbase Support for investigation of issues.

Log output is split into the following streams:

* File based logging

Here logs are written to separate log files filtered by log level, with each log level supporting individual retention policies.

* Console based logging

You can independently configure and control console logs, which provides a convenient method of accessing diagnostic information during debugging scenarios. With console logging, you can fine-tune diagnostic output to suit specific debug scenarios, without interfering with any logging required by Couchbase Support for the investigation of issues.

* Custom logging

For greater flexibility you can implement a custom logging class using the ILogger interface.

## Console based logging

Console based logging is often used to facilitate troubleshooting during development.

Console logs are your go-to resource for diagnostic information. You can easily fine-tune their diagnostic content to meet the needs of a particular debugging scenario, perhaps by increasing the verbosity and-or choosing to focus on messages from a specific domain; to better focus on the problem area.

Changes to console logging are independent of file logging, so you can make change without compromising any files logging streams. It is enabled by default. To change default settings use database’s setLogLevel method to set the required values — see Example 1.

#### Example 1. Change Console Logging Settings

```typescript
database.setLogLevel(LogDomain.ALL, Loglevel.VERBOSE);
```
91 changes: 90 additions & 1 deletion docs/blobs.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,93 @@ id: blobs
sidebar_position: 8
---

# Blobs
# Blobs

> Description — _Couchbase Lite database data model concepts - blobs_
> Related Content — [Databases](databases.md) | [Documents](documents.md) | [Indexing](indexing.md)

## Introduction

Couchbase Lite for Ionic uses blobs to store the contents of images, other media files and similar format files as binary objects.

The blob itself is not stored in the document. It is held in a separate content-addressable store indexed from the document and retrieved only on-demand.

When a document is synchronized, the Couchbase Lite replicator adds an `_attachments` dictionary to the document's properties if it contains a blob — see [Figure 1](#figure-1-sample-blob-document).

## Blob Objects

The blob as an object appears in a document as dictionary property — see, for example avatar in [Figure 1](#figure-1-sample-blob-document).

Other properties include `length` (the length in bytes), and optionally `content_type` (typically, its MIME type).

The blob's data (an image, audio or video content) is not stored in the document, but in a separate content-addressable store, indexed by the `digest` property — see [Using Blobs].

### Constraints

* Couchbase Lite

Blobs can be arbitrarily large. They are only read on demand, not when you load a the document.

* Capella App Services/Sync Gateway

The maximum content size is 20 MB per blob. If a document's blob is over 20 MB, the document will be replicated but not the blob.

## Using Blobs

The Blob API lets you access the blob's data content as in-memory data or as a Stream of Uint8Array.

The code in [Example 1](#example-1-working-with-blobs) shows how you might add a blob to a document and save it to the database. Here we use avatar as the property key and a jpeg file as the blob data.

#### Example 1. Working with Blobs

```typescript
// Example function to simulate fetching binary data for an avatar image
const imageData = await fetchAvatarImageData();

// Create a Blob instance with the image data and content type
const avatarBlob = new Blob('image/jpeg', imageData);

// Retrieve an existing document
let document = await database.getDocument(documentId);

// Assign the Blob to the document under the 'avatar' key
document.setBlob('avatar', avatarBlob);

// Save the updated document back to the database
await database.save(document);
```

## Syncing

When a document containing a blob object is synchronized, the Couchbase Lite replicator generates an `_attachments` dictionary with an auto-generated name for each blob attachment. This is different to the `avatar` key and is used internally to access the blob content.

If you view a sync'd blob document in either Capella's Admin Interface or Couchbase Server's Admin Console, you will see something similar to [Figure 1], which shows the document with its generated `_attachments` dictionary, including the digest.

#### Figure 1. Sample Blob Document

```typescript
{
"_attachments": {
"blob_1": {
"content_type": "image/jpeg",
"digest": "sha1-F1Tfe61RZP4zC9UYT6JFmLTh2s8=",
"length": 8112955,
"revpos": 2,
"stub": true
}
},
"avatar": {
"@type": "blob",
"content_type": "image/jpeg",
"digest": "sha1-F1Tfe61RZP4zC9UYT6JFmLTh2s8=",
"length": 8112955
}
}
```







114 changes: 113 additions & 1 deletion docs/database-prebuilt.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,116 @@ id: database-prebuilt
sidebar_position: 5
---

# Pre-built Database
# Pre-built Database

> Description — _How to Handle Pre-Built Couchbase Lite Databases in Your App_
> Abstract — _This content explains how to include a snapshot of a pre-built database in your package to shorten initial sync time and reduce bandwidth use._

## Overview

*Couchbase Lite* supports pre-built databases. You can pre-load your app with data instead of syncing it from Sync Gateway during startup to minimize consumer wait time (arising from data setup) on initial install and launch of the application.

Avoiding an initial bulk sync reduces startup time and network transfer costs.

It is typically more efficient to download bulk data using the http/ftp stream employed during the application installation than to install a smaller application bundle and then use a replicator to pull in the bulk data.

Pre-loaded data is typically public/shared, non-user-specific data that is static. Even if the data is not static, you can still benefit from preloading it and only syncing the changed documents on startup.

The initial sync of any pre-built database pulls in any content changes on the server that occurred after its incorporation into the app, updating the database.

## To use a Pre-built Database

1. Create a new Couchbase Lite database with the required data set - see [Creating Pre-built database](#creating-pre-built-database).

2. Incorporate the pre-built database with your app bundle as an asset/resource - see [Bundle a Database with an Application](#bundle-a-database-with-an-application).

3. Adjust the start-up logic of your app to check for the presence of the required database. If the database doesn’t already exist, create one using the bundled pre-built database. Initiate a sync to update the data - see [Using Pre-built Database on App Launch](#using-pre-built-database-on-app-launch).

## Creating Pre-built database

These steps should form part of your build and release process:

1. Create a fresh Couchbase Lite database (every time)

:::important
Always start with a fresh database for each app version; this ensures there are no checkpoint issues.

**Otherwise:** You will invalidate the cached checkpoint in the packaged database, and instead reuse the same database in your build process (for subsequent app versions).
:::

2. Pull the data from Sync Gateway into the new Couchbase Lite database

:::important
Ensure the replication used to populate Couchbase Lite database uses the exact same remote URL and replication config parameters (channels and filters) as those your app will use when it is running.

**Otherwise:** …​ there will be a checkpoint mismatch and the app will attempt to pull the data down again

Don’t, for instance, create a pre-built database against a staging Sync Gateway server and use it within a production app that syncs against a production Sync Gateway.
:::

You can use the cblite tool (cblite cp) for this — see: [cblite cp (export, import, push, pull)](https://github.com/couchbaselabs/couchbase-mobile-tools/blob/master/Documentation.md#cp-aka-export-import-push-pull) on GitHub.


3. Create the same indexes the app will use (wait for the replication to finish before doing this).

## Bundle a database with an application

Copy the database into your app package.

Put it in an appropriate place (for example, an assets or resource folder).

Where the platform permits you can zip the database.

**Alternatively:**​ rather than bundling the database within the app, the app could pull the database down from a CDN server on launch.

## Database Encryption

If you are using en encrypted database, note that Database.copy does not change the encryption key. The encryption key specified in the config when opening the database is the encryption key used for both the original database and copied database.

If you copied an un-encrypted database and want to apply encryption to the copy, or if you want to change (or remove) the encryption key applied to the copy:

1. Provide the original encryption-key (if any) in the database copy's configuration using DatabaseConfiguration.getEncryptionKey().

2. Open the database copy

3. Use Database.setEncryptionKey() on the database copy to set the required encryption key.

:::tip
To remove encryption on the copy, provide a null encryption-key.
:::

## Using Pre-built Database on App Launch

1. Locate the pre-packaged database (for example, in the assets or other resource folder)

2. Copy the pre-packaged database to the required location

Use the API's Database.copy method — see: [Example 1](#example-1-decompress-and-copy-database-using-api). This ensures that a unique UUID is generated for each copy.

:::important
Do not copy the database using any other method.

**Otherwise:** Each copy of the app will invalidate the other apps' checkpoints because a new UUID was not generated.
:::

3. Open the database; you can now start querying the data and using it.

4. Start a pull replication, to sync any changes.

The replicator uses the pre-built database's checkpoint as the timestamp to sync from; only documents changed since then are synced.

:::note
Start your normal application logic immediately, unless it is essential to have the absolute up-to-date data set to begin. That way the user is not kept hanging around watching a progress indicator. They can begin interacting with your app whilst any out-of-data data is being updated.
:::

#### Example 1. Decompress and Copy Database using API

```typescript
// Check if the database already exists
if (!await Database.exists(dbName, null)) {
// Copy the database from the sourcePath to the app's directory
await Database.copy(sourcePath, dbName, new DatabaseConfiguration());
}
```


Loading