AI Journaling with Reflection Using Google Gemini and Vertex AI in Firebase

May 8, 2025
Product Updates
AI Journaling with Reflection Using Google Gemini and Vertex AI in Firebase

The Challenge: Build a Fast and Secure AI Integration in our Flutter App

Reflection is our AI-powered journaling app designed to help users gain deeper insights into their thoughts and experiences. When we set out to build Reflection, we faced a compelling challenge: how could we transform the traditional journaling experience by making AI interactions both insightful and seamless? Our users wanted to gain deeper understanding from their journal entries without sacrificing privacy or performance.

Our solution: Integrate Google Gemini using Vertex AI in Firebase and Flutter and to create a secure journaling experience that delivers meaningful personalized insights with millisecond response times.

Our Implementation 

Phase 1: Building the Journaling Companion

We started by creating an AI-enhanced editor where users can write entries and receive thoughtful questions, guidance, or feedback to help them explore their thoughts more deeply.

Vertex AI in Firebase Solution

After exploring several approaches, we found that Vertex AI in Firebase provided the ideal combination of performance, security, and ease of integration for our Flutter app.

Architecture Overview

[User Device: Flutter App]
        |
        v
[Firebase App Check] <---+
        |                |
        v                |
[Firebase Remote Config] |
        |                |
        v                |
   [Depth Service]       |
        |                |
        v                |
[Vertex AI in Firebase]--+
        |
        v
[AI Response to User]

Our current architecture leverages Flutter and Firebase's ecosystem:

Flutter App: Multi-platform UI built with Flutter

Firebase App Check: Security layer ensuring only legitimate clients access our AI

Firebase Remote Config: Dynamic management of prompts and AI settings

Vertex AI in Firebase: Secure, server-side AI processing with Gemini models

Depth Service: Core service managing AI interactions and context

Implementing Firebase App Check

Security was a top priority. App Check ensures that only verified clients can access our Vertex AI resources.

Step-by-Step Implementation

1. Add Firebase dependencies

dependencies:
firebase_app_check: latest_version


2. Initialize Firebase and App Check

Future<void> main() async  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: firebaseOptions());
  await setFirebaseAppCheck();
  runApp(MyApp());
}

3. Configure App Check for different environments

Future setFirebaseAppCheck() async {
  try {
    if (kDebugMode) {
      await FirebaseAppCheck.instance.activate(
        webProvider: ReCaptchaV3Provider('Your_Recaptcha_Key'),
        androidProvider: AndroidProvider.debug,
        appleProvider: AppleProvider.debug,
      );
      _log.d('Activated FirebaseAppCheck in debug mode');
      return;
    }
    await FirebaseAppCheck.instance.activate(
      webProvider: ReCaptchaV3Provider('Your_Recaptcha_Key'),
      androidProvider: AndroidProvider.playIntegrity,
      appleProvider: AppleProvider.appAttest,
    );
    _log.i('FirebaseAppCheck activated');
  } catch (e, s) {
    _log.e('Error activating FirebaseAppCheck', error: e, stackTrace: s);
  }
}

Troubleshooting App Check

We initially encountered an issue where App Check showed 0% verified requests. After consulting with Firebase support, we discovered a critical step was missing: connecting App Check to the Vertex AI model instance.

// The correct way to initialize Vertex AI with App Check
final model = FirebaseVertexAI.instanceFor(appCheck: FirebaseAppCheck.instance)
    .generativeModel(model: 'YOUR_MODEL');

This small but crucial detail was the key to making our security layer work properly. You can find more details in this Firebase user voice thread.

Phase 2: Semantic Search

We expanded our AI capabilities into search to support natural language search, allowing users to ask questions about past entries in conversational language. For example, users can ask "Where did I go on vacation last summer?" or “What are my self-limiting beliefs?” and get relevant insights and source entries from their journal history.

Dynamic AI Configuration with Remote Config

We use Firebase Remote Config to adjust AI behavior without app updates. This allows us to:

• Switch between AI models (Gemini 1.5 Pro, Gemini 2.0 Flash, etc.)

• Update system prompts and templates

• Adjust temperature and other generation parameters

Firebase Remote Config dashboard for AI settings

Our configuration structure:

{
  "ai_config": {
    "provider": "gemini",
    "model": "gemini-2.0-flash",
    "temperature": 0.7,
    "maxTokens": 999999,
    "maxInputSize": 2000000,
    "minInputSize": 10,
    "safetySettings": {}
  },
  "ai_system_prompt": "You are a helpful journaling sidekick.",
  "ai_entry_prompt_template": "...",
  "ai_journal_search_prompt_template": "...",
  "ai_today_page_personalized_prompt_template": "..."
}

Initializing Vertex AI

class GeminiService implements GenerativeAiService {
  final _log = getLogger('GeminiService');
  late final GenerativeModel _model;
  void initializeGemini(AIConfig config) {
    try {
      _model = FirebaseVertexAI.instanceFor(appCheck: FirebaseAppCheck.instance).generativeModel(
        model: config.model,
        generationConfig: getGenerationConfig(config),
        safetySettings: getSafetySettings(config),
      );
      _log.i('Gemini service initialized successfully');
    } catch (e, s) {
      _log.e('Failed to initialize Gemini: Error: $e, StackTrace: $s');
    }
  }
}

Performance Optimization Techniques

To achieve our fast response times, we implemented several optimization strategies:

1. Client-side caching: We cache recent AI responses to avoid redundant calls

2. Streaming responses: Implementing streamed responses for immediate feedback

3. Request batching: Grouping multiple small requests into single calls

4. Prompt optimization: Carefully crafting prompts to minimize token usage

// Example of streaming implementation
Future<void> streamResponse(String prompt) async {
  final content = [Content.text(prompt)];
  
  try {
    final stream = _model.generateContentStream(content);
    
    await for (final response in stream) {
      // Process and display each chunk as it arrives
      final text = response.text;
      if (text != null) {
        _updateMarkdownUI(text);
      }
    }
  } catch (e) {
    _log.e('Error streaming response: $e');
    rethrow;
  }
}

Getting Started with Vertex AI in Firebase and Flutter

For developers looking to implement similar functionality, here's a simplified guide:

1. Set up Firebase in your Flutter project

▪ Install the FlutterFire CLI:  

dart pub global activate flutterfire_cli

▪ Configure Firebase:

 flutterfire configure

2. Add the necessary dependencies

In the terminal, run:
```bash
flutter pub add firebase_core firebase_app_check firebase_remote_config firebase_vertex_ai
```

dependencies:
  firebase_core: latest_version
  firebase_app_check: latest_version
  firebase_remote_config: latest_version
  firebase_vertex_ai: latest_version

3. Enable Vertex AI in Firebase Console

▪ Navigate to the Firebase Console

▪ Select your project

▪ Go to Product Categories > AI > Vertex AI in Firebase

▪ Enable the service and select your preferred models

4. Implement App Check

▪ Follow our implementation example above

▪ Don't forget to connect App Check to your Vertex AI instance!

5. Create your AI service layer

▪ Implement a service class similar to our GeminiService

▪ Use dependency injection for easier testing and maintenance

See It In Action

Here is a quick video showing the new AI implementation in app:

Experience Reflection’s new AI implementation on our Flutter-powered, fully native apps live today on iOS, Android, MacOS, and Web

Lessons Learned

Our journey with Vertex AI in Firebase taught us several valuable lessons:

1. Security first: Implementing App Check from the beginning saves headaches later

2. Test on all platforms: Each platform (iOS, Android, Web) has unique implementation details

3. Start with streaming: Building for streaming responses from the start provides better UX

4. Monitor token usage: Use Firebase’s built token usage analytics to manage costs effectively

5. Remote Config is powerful: Leverage Remote Config to tune AI behavior without app updates

6. Server-side processing has tradeoffs: Our initial implementation used Flowise for server-side AI processing, which introduced latency issues. Moving to Vertex AI in Firebase significantly improved performance while maintaining security.

Impact and Results

The integration of Vertex AI in Firebase has transformed our user experience. Our users don't know or care that we moved our AI integration from server-side to client, implemented response caching, or managed prompts with Remote Config. What they do care about is speed, quality of responses, and data security. With this latest release, users have been loving the changes - we’ve heard it directly from our users and are also seeing it in the user adoption numbers.

  • +60% increase in AI feature usage after switching to client side using Vertex AI in Firebase
  • < 300 ms AI response time under real‑world load after switching to Vertex AI in Firebase

Wrapping Up & Looking Ahead

Integrating Vertex AI in Firebase with Flutter has been transformative for Reflection. The combination of Flutter's multi-platform capabilities and Firebase's secure, scalable AI infrastructure has allowed us to deliver a truly modern journaling experience.

We're grateful to the Firebase and Flutter teams for creating tools that enable small development teams like ours to build sophisticated AI-powered applications. As these technologies continue to evolve, we're excited to push the boundaries of what's possible in personal journaling and self-reflection.

What's Next: Enhanced Voice Mode

While today's experience revolves around text, our next big release will expand beyond that. First voice based journaling, and beyond that live conversational experience using Gemini’s (newly announced!) Live API. We are excited to share our journey working with it once we finish building!

Try Reflection today and experience the power of Flutter, Firebase and Vertex AI — we can’t wait to hear what you think!

Written by Isaac Adariku, Lead Flutter Developer at Reflection.

The Challenge: Build a Fast and Secure AI Integration in our Flutter App

Reflection is our AI-powered journaling app designed to help users gain deeper insights into their thoughts and experiences. When we set out to build Reflection, we faced a compelling challenge: how could we transform the traditional journaling experience by making AI interactions both insightful and seamless? Our users wanted to gain deeper understanding from their journal entries without sacrificing privacy or performance.

Our solution: Integrate Google Gemini using Vertex AI in Firebase and Flutter and to create a secure journaling experience that delivers meaningful personalized insights with millisecond response times.

Our Implementation 

Phase 1: Building the Journaling Companion

We started by creating an AI-enhanced editor where users can write entries and receive thoughtful questions, guidance, or feedback to help them explore their thoughts more deeply.

Vertex AI in Firebase Solution

After exploring several approaches, we found that Vertex AI in Firebase provided the ideal combination of performance, security, and ease of integration for our Flutter app.

Architecture Overview

[User Device: Flutter App]
        |
        v
[Firebase App Check] <---+
        |                |
        v                |
[Firebase Remote Config] |
        |                |
        v                |
   [Depth Service]       |
        |                |
        v                |
[Vertex AI in Firebase]--+
        |
        v
[AI Response to User]

Our current architecture leverages Flutter and Firebase's ecosystem:

Flutter App: Multi-platform UI built with Flutter

Firebase App Check: Security layer ensuring only legitimate clients access our AI

Firebase Remote Config: Dynamic management of prompts and AI settings

Vertex AI in Firebase: Secure, server-side AI processing with Gemini models

Depth Service: Core service managing AI interactions and context

Implementing Firebase App Check

Security was a top priority. App Check ensures that only verified clients can access our Vertex AI resources.

Step-by-Step Implementation

1. Add Firebase dependencies

dependencies:
firebase_app_check: latest_version


2. Initialize Firebase and App Check

Future<void> main() async  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: firebaseOptions());
  await setFirebaseAppCheck();
  runApp(MyApp());
}

3. Configure App Check for different environments

Future setFirebaseAppCheck() async {
  try {
    if (kDebugMode) {
      await FirebaseAppCheck.instance.activate(
        webProvider: ReCaptchaV3Provider('Your_Recaptcha_Key'),
        androidProvider: AndroidProvider.debug,
        appleProvider: AppleProvider.debug,
      );
      _log.d('Activated FirebaseAppCheck in debug mode');
      return;
    }
    await FirebaseAppCheck.instance.activate(
      webProvider: ReCaptchaV3Provider('Your_Recaptcha_Key'),
      androidProvider: AndroidProvider.playIntegrity,
      appleProvider: AppleProvider.appAttest,
    );
    _log.i('FirebaseAppCheck activated');
  } catch (e, s) {
    _log.e('Error activating FirebaseAppCheck', error: e, stackTrace: s);
  }
}

Troubleshooting App Check

We initially encountered an issue where App Check showed 0% verified requests. After consulting with Firebase support, we discovered a critical step was missing: connecting App Check to the Vertex AI model instance.

// The correct way to initialize Vertex AI with App Check
final model = FirebaseVertexAI.instanceFor(appCheck: FirebaseAppCheck.instance)
    .generativeModel(model: 'YOUR_MODEL');

This small but crucial detail was the key to making our security layer work properly. You can find more details in this Firebase user voice thread.

Phase 2: Semantic Search

We expanded our AI capabilities into search to support natural language search, allowing users to ask questions about past entries in conversational language. For example, users can ask "Where did I go on vacation last summer?" or “What are my self-limiting beliefs?” and get relevant insights and source entries from their journal history.

Dynamic AI Configuration with Remote Config

We use Firebase Remote Config to adjust AI behavior without app updates. This allows us to:

• Switch between AI models (Gemini 1.5 Pro, Gemini 2.0 Flash, etc.)

• Update system prompts and templates

• Adjust temperature and other generation parameters

Firebase Remote Config dashboard for AI settings

Our configuration structure:

{
  "ai_config": {
    "provider": "gemini",
    "model": "gemini-2.0-flash",
    "temperature": 0.7,
    "maxTokens": 999999,
    "maxInputSize": 2000000,
    "minInputSize": 10,
    "safetySettings": {}
  },
  "ai_system_prompt": "You are a helpful journaling sidekick.",
  "ai_entry_prompt_template": "...",
  "ai_journal_search_prompt_template": "...",
  "ai_today_page_personalized_prompt_template": "..."
}

Initializing Vertex AI

class GeminiService implements GenerativeAiService {
  final _log = getLogger('GeminiService');
  late final GenerativeModel _model;
  void initializeGemini(AIConfig config) {
    try {
      _model = FirebaseVertexAI.instanceFor(appCheck: FirebaseAppCheck.instance).generativeModel(
        model: config.model,
        generationConfig: getGenerationConfig(config),
        safetySettings: getSafetySettings(config),
      );
      _log.i('Gemini service initialized successfully');
    } catch (e, s) {
      _log.e('Failed to initialize Gemini: Error: $e, StackTrace: $s');
    }
  }
}

Performance Optimization Techniques

To achieve our fast response times, we implemented several optimization strategies:

1. Client-side caching: We cache recent AI responses to avoid redundant calls

2. Streaming responses: Implementing streamed responses for immediate feedback

3. Request batching: Grouping multiple small requests into single calls

4. Prompt optimization: Carefully crafting prompts to minimize token usage

// Example of streaming implementation
Future<void> streamResponse(String prompt) async {
  final content = [Content.text(prompt)];
  
  try {
    final stream = _model.generateContentStream(content);
    
    await for (final response in stream) {
      // Process and display each chunk as it arrives
      final text = response.text;
      if (text != null) {
        _updateMarkdownUI(text);
      }
    }
  } catch (e) {
    _log.e('Error streaming response: $e');
    rethrow;
  }
}

Getting Started with Vertex AI in Firebase and Flutter

For developers looking to implement similar functionality, here's a simplified guide:

1. Set up Firebase in your Flutter project

▪ Install the FlutterFire CLI:  

dart pub global activate flutterfire_cli

▪ Configure Firebase:

 flutterfire configure

2. Add the necessary dependencies

In the terminal, run:
```bash
flutter pub add firebase_core firebase_app_check firebase_remote_config firebase_vertex_ai
```

dependencies:
  firebase_core: latest_version
  firebase_app_check: latest_version
  firebase_remote_config: latest_version
  firebase_vertex_ai: latest_version

3. Enable Vertex AI in Firebase Console

▪ Navigate to the Firebase Console

▪ Select your project

▪ Go to Product Categories > AI > Vertex AI in Firebase

▪ Enable the service and select your preferred models

4. Implement App Check

▪ Follow our implementation example above

▪ Don't forget to connect App Check to your Vertex AI instance!

5. Create your AI service layer

▪ Implement a service class similar to our GeminiService

▪ Use dependency injection for easier testing and maintenance

See It In Action

Here is a quick video showing the new AI implementation in app:

Experience Reflection’s new AI implementation on our Flutter-powered, fully native apps live today on iOS, Android, MacOS, and Web

Lessons Learned

Our journey with Vertex AI in Firebase taught us several valuable lessons:

1. Security first: Implementing App Check from the beginning saves headaches later

2. Test on all platforms: Each platform (iOS, Android, Web) has unique implementation details

3. Start with streaming: Building for streaming responses from the start provides better UX

4. Monitor token usage: Use Firebase’s built token usage analytics to manage costs effectively

5. Remote Config is powerful: Leverage Remote Config to tune AI behavior without app updates

6. Server-side processing has tradeoffs: Our initial implementation used Flowise for server-side AI processing, which introduced latency issues. Moving to Vertex AI in Firebase significantly improved performance while maintaining security.

Impact and Results

The integration of Vertex AI in Firebase has transformed our user experience. Our users don't know or care that we moved our AI integration from server-side to client, implemented response caching, or managed prompts with Remote Config. What they do care about is speed, quality of responses, and data security. With this latest release, users have been loving the changes - we’ve heard it directly from our users and are also seeing it in the user adoption numbers.

  • +60% increase in AI feature usage after switching to client side using Vertex AI in Firebase
  • < 300 ms AI response time under real‑world load after switching to Vertex AI in Firebase

Wrapping Up & Looking Ahead

Integrating Vertex AI in Firebase with Flutter has been transformative for Reflection. The combination of Flutter's multi-platform capabilities and Firebase's secure, scalable AI infrastructure has allowed us to deliver a truly modern journaling experience.

We're grateful to the Firebase and Flutter teams for creating tools that enable small development teams like ours to build sophisticated AI-powered applications. As these technologies continue to evolve, we're excited to push the boundaries of what's possible in personal journaling and self-reflection.

What's Next: Enhanced Voice Mode

While today's experience revolves around text, our next big release will expand beyond that. First voice based journaling, and beyond that live conversational experience using Gemini’s (newly announced!) Live API. We are excited to share our journey working with it once we finish building!

Try Reflection today and experience the power of Flutter, Firebase and Vertex AI — we can’t wait to hear what you think!

Written by Isaac Adariku, Lead Flutter Developer at Reflection.

Gain clarity and peace of mind, wherever you are.

Download Reflection to start journaling today.
Scan with phone.
Download App