Skip to content
5 changes: 5 additions & 0 deletions pages/actions/read-keychain.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Callout } from 'nextra/components'

# readKeychain

The `readKeychain` action retrieves previously stored data from the device's secure keychain (iOS) or equivalent secure storage (Android), allowing access to sensitive information that was stored with the highest level of OS security protection.
Expand Down Expand Up @@ -33,10 +35,13 @@ Button:

## JavaScript Usage

<Callout type="warning">
It is only available in YAML, as this calls a async function whose return type is Future and we use callbacks to handle the result. Our JS is sync and we cannot use async/await in JS.
</Callout>

## Notes


- This action reads from the device's secure keychain or equivalent OS security storage.
- Unlike the `getSecureStorage` action, this operation is asynchronous and must use callbacks even in JavaScript.
- The retrieved data is converted back to its original data type (string, number, boolean, or object).
Expand Down
19 changes: 19 additions & 0 deletions pages/apis/define-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,22 @@ API:
title: "${productTitle}" # example of a dynamic data that is set based on the inputs
source: MyApp # example of a static data that is always passed
```

## apiSecureStorage

For API calls, you can use `apiSecureStorage.key` to directly access secure storage values within the API context. This approach doesn't require any callbacks or async handling.

### Example

```yaml
API:
createToDo:
url: http://192.168.18.163:3000/api/test
method: 'POST'
headers:
Context: apiKey ${apiSecureStorage.newdata}
body:
records:
- fields:
desc: "${apiSecureStorage.newdata} ${ensemble.storage.counter}"
```
6 changes: 6 additions & 0 deletions pages/firebase/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,11 @@
},
"firestore-operations": {
"title": "Firestore"
},
"firebase-functions": {
"title": "Firebase Functions"
},
"firebase-appcheck": {
"title": "Firebase Appcheck"
}
}
7 changes: 6 additions & 1 deletion pages/firebase/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,14 @@ After we have replaced the placeholder hashtags (#) in our configuration file, i

#### Update Environmental Variables

Within our Ensemble application, navigate to the settings section and look for the option to manage environmental variables. Here, we'll create two new variables:
Within our Ensemble application, navigate to the settings section and look for the option to manage environmental variables. Here, we'll create the following variables:
- `api_providers`: Set the value of this variable to `firestore`. This tells our app to use Firebase Firestore as a data provider.
- `firestore_config`: This is where you'll paste the complete configuration file we created earlier, including the replaced values from our downloaded configuration files.
- `firebase_config`: Similar to `firestore_config`, this variable is required when using Firebase Functions or Firebase App Check. Use the same configuration file format and values as above.

<Callout type="info">
The `firebase_config` environment variable follows the same structure and values as `firestore_config`. It's specifically needed when implementing Firebase Functions or Firebase App Check in your Ensemble application.
</Callout>

![Environment Variables](/images/firebase/envVari.png)

Expand Down
111 changes: 111 additions & 0 deletions pages/firebase/firebase-appcheck.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { Callout } from 'nextra/components'

# Firebase App Check Configuration

[Firebase App Check](https://firebase.google.com/docs/app-check) helps protect your API resources from abuse by preventing unauthorized clients from accessing your backend resources. Ensemble platform provides seamless integration with Firebase App Check, ensuring that only legitimate requests from your verified app can access your Firebase services.

Unlike traditional API security measures, App Check provides automatic app verification that works transparently with your existing Firebase services. App Check is an excellent security addition for Ensemble applications because it provides automatic app verification, protection against abuse, seamless integration with Firebase services, and minimal performance impact.

Now, let's dive into configuring Firebase App Check for our Ensemble application:

<Callout type="warning">
App Check integration requires proper Firebase configuration. Ensure your Firebase project is set up before proceeding. Learn how to configure it [here](configuration.mdx#2-configure-ensemble-app).
</Callout>


## 1. Environment Configuration
Within our Ensemble application, navigate to the settings section and look for the option to manage environmental variables. Here, we'll create the environment variable for appcheck as follows:

**Example**:
![App Check](/images/firebase/appcheck.png)
**Explanation**:
Enables App Check verification for all Firebase API calls in your Ensemble application.

## 2. Types of App Check Operations

App Check provides different verification methods for different platforms and environments. Here's a breakdown of the main operations and configurations:

### Debug Token Setup:
Debug tokens are essential for development and testing environments where app verification might not work as expected. To run application with appcheck (Dev environment), you would need to register debug token in firebase console's appcheck section for your project.
For release, you will need to register SHA 256 token of your app with your respective platform (Appstore or Google Play).

1. **Example (Android Debug Token Extraction)**:
```bash
# Run the application
flutter run

# Extract debug token from logs
adb logcat | grep "App Check"
```
**Explanation**:
- `flutter run`: Starts your application in debug mode.
- `adb logcat | grep "App Check"`: Filters log output to show App Check debug token.
- Look for output like: `App Check debug token: 12345678-ABCD-EFGH-IJKL-123456789012`

2. **Example (iOS Debug Token Configuration)**:
```yaml
# In Xcode scheme configuration
Environment Variables:
FIRDebugEnabled: YES
FIRAppCheckDebugEnabled: YES
```
**Explanation**:
- `FIRDebugEnabled`: Enables Firebase debug logging.
- `FIRAppCheckDebugEnabled`: Specifically enables App Check debug token generation.


### Conditional App Check:
Control App Check usage on a per-API basis depending on your security requirements.

**Example (Secure Firebase Function)**:
```yaml
secureFunction:
type: firebaseFunction
name: sensitiveOperation
# App Check enabled by default when firebase_app_check=true
data:
userId: ${currentUser.id}
operation: transfer
```


## 3. Response and Monitoring of App Check Operations

When performing Firebase operations with App Check enabled, you can monitor verification status and handle failures appropriately. Below are examples demonstrating how to handle App Check responses and implement monitoring.

### 1. Making API calls with App Check monitoring:
```yaml
invokeAPI:
name: secureFirestoreOperation
inputs:
userId: ${userID}
onResponse:
executeCode:
body: |-
console.log('App Check verification successful');

onError:
executeCode:
body: |-
console.log('App Check verification failed:', response.error);
```


## 4. Troubleshooting Common App Check Issues

### Debug Token Issues
<Callout type="error">
**Debug Token Not Working**: Ensure the token is correctly copied without extra spaces, verify it's added to the correct app in Firebase Console, and check that debug environment variables are properly set.
</Callout>

### Production Verification Failures
<Callout type="error">
**App Check Failing in Production**: Verify Play Integrity/App Attest is properly configured, check that your app is signed with correct certificates, and ensure your app is published or in internal testing.
</Callout>

### Web Configuration Issues
<Callout type="error">
**Web App Check Issues**: Verify reCAPTCHA configuration and site keys, check that your domain is whitelisted, and ensure the reCAPTCHA script loads correctly.
</Callout>

By implementing Firebase App Check with these operations, you can significantly enhance the security of your Ensemble application. App Check's real-time verification capabilities and seamless integration make it a powerful tool for protecting your Firebase resources from unauthorized access and abuse.
156 changes: 156 additions & 0 deletions pages/firebase/firebase-functions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
---
title: "Calling Firebase Functions APIs"
description: "Learn how to integrate and call Firebase Functions in your Ensemble applications"
---

import { Callout } from 'nextra/components'

# Calling Firebase Functions APIs

Firebase Functions allows you to run backend code in response to events triggered by Firebase features and HTTPS requests. Ensemble platform provides seamless integration with Firebase Functions, enabling you to call serverless functions from your app effortlessly.

Unlike traditional server setups, Firebase Functions offers a serverless architecture that automatically scales based on demand. Firebase Functions is an excellent choice for Ensemble applications because it provides automatic scaling, secure execution environment, easy deployment, and simplified backend logic without server management.

Now, let's dive into implementing Firebase Functions in our Ensemble application:

<Callout type="warning">
Firebase function integration requires proper Firebase configuration. Ensure your Firebase project is set up before proceeding. Learn how to configure it [here](configuration.mdx#2-configure-ensemble-app).
</Callout>



## 1. Environment Configuration

### Setting Up API Providers
Within our Ensemble application, navigate to the settings section and look for the option to manage environmental variables. Here, we'll create two new variables:
- `api_providers`: Set the value of this variable to `firebase`. This tells our app to use Firebase function as a api provider.

**Example**:
![All Apps](/images/firebase/firebasefunction.png)

<Callout type="info">
**Note:** You can use multiple api_providers by using comma-separated values (e.g., firestore,firebase)
</Callout>


## 2. Types of Firebase Functions Operations

Firebase Functions offers various ways to interact with your serverless backend. Here's a breakdown of core operations along with demo API calls for our Ensemble app:

### Basic Function Call:
This operation calls a Firebase Function without any parameters.

**Example (Simple function call):**
```yaml
testFunction:
type: firebaseFunction
name: helloWorld
```

**Explanation:**
- `type: firebaseFunction`: Specifies that the operation is for Firebase Functions
- `name`: The name of the Firebase Function to call

### Function Call with Data:
This operation calls a Firebase Function with input parameters.

**Example (Function with parameters):**
```yaml
createUser:
inputs:
- email
- displayName
type: firebaseFunction
name: createCustomUser
data:
email: ${email}
displayName: ${displayName}
role: user
createdAt: ${new Date().toISOString()}
```

**Explanation:**
- `inputs`: Dynamic variables that can be passed to the function
- `data`: The payload sent to the Firebase Function
- Values can be static or use dynamic variables with `${variableName}` syntax

## 3. Response Handling of Firebase Functions

When performing Firebase Functions operations, you may need to handle responses and errors appropriately. Below are common patterns for handling API responses in your Ensemble app.

### 1. Making an API call:
```yaml
invokeAPI:
name: myFunction
inputs:
userId: ${userID}
```

You can also use `onResponse` & `onError` on Firebase Function API calls and perform operations on the response.

### 2. Complete Function Definition with Response Handling:
```yaml
API:
getUserData:
inputs:
- userId
type: firebaseFunction
name: fetchUserProfile
data:
userId: ${userId}
includeStats: true
onResponse:
executeCode:
body: |-
console.log('User data fetched successfully');
console.log(response.body);
userNameText.text = response.body.user.name;
userEmailText.text = response.body.user.email;
onError:
executeCode:
body: |-
console.log('Failed to fetch user data');
console.log(response.body);
errorText.text = "Error: " + response.body;

```

### 3. Using response in UI Components:
Firebase functions will work similar to simple http APIs and their responses can be used in UI Components:

```yaml

Column:
styles:
visible: '${getUserData.isSuccess ? true : false}'
children:
- Text:
id: userNameText
text: "Name: ${getUserData.body.user.name}"
- Text:
id: userEmailText
text: "Email: ${getUserData.body.user.email}"
- Text:
text: "Last Login: ${getUserData.body.user.lastLogin}"

```



## 4. Troubleshooting

### Common Issues
- Ensure Firebase Functions are deployed and accessible
- Verify function names match exactly (case-sensitive)
- Check that the Firebase project is correctly configured
- Confirm internet connectivity for function calls

### Debug Tips
- Use console.log in onResponse and onError handlers to inspect responses
- Check Firebase Console for function logs and error details
- Test functions independently using Firebase Console or Postman
- Verify function permissions and authentication requirements

<Callout type="success">
By using these operations, you can efficiently call Firebase Functions from your Ensemble application. Firebase Functions' serverless architecture makes it a powerful solution for any backend logic your application needs.
</Callout>
1 change: 1 addition & 0 deletions pages/widgets/Image.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ You can manage your assets using Ensemble Studio. [See how](/assets)
| resizedHeight | integer | Images will be automatically resized (default to 800 width with no height set) before rendering. If you know the rough image height, set this number to be the same or a slightly larger height to optimize the loading time. To maintain the original aspect ratio, set either resizedWidth or resizedHeight, but not both. This setting is not supported on Web. |
| visibilityTransitionDuration | integer | Specify the duration in seconds when a widget animates between visible and not visible state. Note that setting this value will cause the widget to still occupy the UI space even when it is not visible. |
| placeholderColor | integer or string | The placeholder color while the image is loading `transparent` `black` `blue` `white` `red` `grey` `teal` `amber` `pink` `purple` `yellow` `green` `brown` `cyan` `indigo` `lime` `orange` |
| colorFilter | object | Applies color filter to the image. |

### styles.backgroundGradient

Expand Down
1 change: 1 addition & 0 deletions pages/widgets/avatar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ The Avatar Widget provides a visual representation of a user or entity, typicall
|:-----------------|:---------------------------------------|:--------------------------------------------------|
| placeholderColor | [Color](/widgets/types#Color) | The placeholder color while the image is loading. |
| fit | [Fit](/widgets/types#Fit) | How to fit the image within the dimensions |
| colorFilter | object | Applies color filter to Avatar |

### Box Styles (Inherited)
This widget also inherits these styles
Expand Down
1 change: 1 addition & 0 deletions pages/widgets/carousel.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ The Carousel Widget allows you to create and render carousels, enabling the pres
| cacheKey | string | Pass a cacheKey if you want to keep the carousel's item position when it was recreated |
| buildOnDemand | boolean | Build the carousel items only when its visible in the screen. Default - false |
| buildOnDemandLength | integer | Build the carousel items when its visible in the screen only when the item is greater or equal to this length. Default - 6 |
| colorFilter | object | Applies color filter to whole carousel | |


### Box Styles (Inherited)
Expand Down
Loading