Skip to main content
RapidDev - Software Development Agency
flutterflow-tutorials

How to Use Machine Learning for Predictive Analytics in FlutterFlow

Add machine learning predictive analytics to your FlutterFlow app by extracting behavioral features from Firestore events, calling an ML model endpoint (BigQuery ML or Cloud AI Platform) via a Cloud Function, and storing churn scores and purchase probabilities back in Firestore user documents. Trigger automated re-engagement flows when scores cross thresholds. Never train a churn model on only churned users — you need both churned and retained users.

What you'll learn

  • Extract behavioral features from Firestore events for ML input
  • Call a BigQuery ML churn prediction model from a Cloud Function
  • Store prediction scores in Firestore user documents for real-time access in FlutterFlow
  • Trigger automated re-engagement flows when a user's churn score crosses a threshold
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner11 min read60-90 minFlutterFlow Pro+ (Cloud Functions required)March 2026RapidDev Engineering Team
TL;DR

Add machine learning predictive analytics to your FlutterFlow app by extracting behavioral features from Firestore events, calling an ML model endpoint (BigQuery ML or Cloud AI Platform) via a Cloud Function, and storing churn scores and purchase probabilities back in Firestore user documents. Trigger automated re-engagement flows when scores cross thresholds. Never train a churn model on only churned users — you need both churned and retained users.

Predictive Analytics Without a Data Science Team

Machine learning for predictive analytics sounds daunting, but BigQuery ML lets you train and deploy a logistic regression or gradient boosted trees model using SQL syntax — no Python or ML frameworks required. The data comes from behavioral events you are already logging in Firestore (or can start logging today): session count, screens visited, feature usage, and last active date. A Cloud Function extracts these features, calls the BigQuery ML prediction endpoint, and writes the score back to Firestore. FlutterFlow reads the score from the user document to personalize the UI — showing win-back offers to high-churn-risk users or upsell prompts to high-purchase-probability users. The whole pipeline runs on Google Cloud with no external ML infrastructure.

Prerequisites

  • FlutterFlow project with Firebase Firestore and user behavioral event logging
  • Google Cloud project with BigQuery enabled (linked to your Firebase project)
  • A minimum of 500 labeled training examples (churned and retained users) for meaningful model accuracy
  • FlutterFlow Pro plan for Cloud Functions

Step-by-step guide

1

Define and log the behavioral features you will use for prediction

Machine learning models are only as good as their input features. Before thinking about models, decide what user behavior predicts churn or purchase in your app. Common high-signal features: `daysSinceLastActive` (most predictive for churn), `totalSessionsLast30Days`, `featureUsageCount` (how many distinct features used), `profileCompletionPercent`, `notificationOptIn` (boolean), `purchaseCount`, `averageSessionDurationSeconds`. Ensure these are being logged to Firestore. If they are not, add On Page Load tracking (see the navigation patterns tutorial) and aggregate them daily into a `userStats` document per user. The `userStats` collection should have one document per user, keyed by UID, with all computed features as numeric fields.

Expected result: A `userStats` collection exists in Firestore with one document per user containing numeric feature fields updated daily.

2

Export Firestore features to BigQuery for model training

Firebase has a native BigQuery export integration. In the Firebase console, go to Project Settings > Integrations > BigQuery > Link. This exports Firebase Analytics events to BigQuery automatically. For your Firestore `userStats` features, set up a scheduled Cloud Function that exports the collection to a BigQuery table using the BigQuery client library. Create a BigQuery table named `user_features` with columns matching your `userStats` fields plus a `churned` column (1 if the user has not been active in 30 days, 0 if active). This labeled dataset is what you will train the model on.

functions/exportToBigQuery.js
1const { onSchedule } = require('firebase-functions/v2/scheduler');
2const { initializeApp } = require('firebase-admin/app');
3const { getFirestore } = require('firebase-admin/firestore');
4const { BigQuery } = require('@google-cloud/bigquery');
5
6initializeApp();
7
8exports.exportUserStatsToBigQuery = onSchedule('every 24 hours', async () => {
9 const db = getFirestore();
10 const bq = new BigQuery();
11 const dataset = bq.dataset('analytics');
12 const table = dataset.table('user_features');
13
14 const snapshot = await db.collection('userStats').get();
15 const rows = [];
16 const now = Date.now();
17
18 snapshot.forEach((doc) => {
19 const d = doc.data();
20 const lastActive = d.lastActiveAt?.toDate()?.getTime() || 0;
21 const daysSinceLastActive = Math.floor((now - lastActive) / 86400000);
22 rows.push({
23 userId: doc.id,
24 daysSinceLastActive,
25 totalSessionsLast30Days: d.totalSessionsLast30Days || 0,
26 featureUsageCount: d.featureUsageCount || 0,
27 purchaseCount: d.purchaseCount || 0,
28 profileCompletionPercent: d.profileCompletionPercent || 0,
29 churned: daysSinceLastActive > 30 ? 1 : 0,
30 exportedAt: new Date().toISOString(),
31 });
32 });
33
34 if (rows.length > 0) {
35 await table.insert(rows);
36 }
37 console.log(`Exported ${rows.length} user stats to BigQuery`);
38});

Expected result: A BigQuery table `analytics.user_features` is populated with user feature rows daily.

3

Train a churn prediction model in BigQuery ML

In the BigQuery console, run the CREATE MODEL SQL statement to train a logistic regression classifier. Use the `user_features` table with `churned` as the label column. BigQuery ML handles feature scaling and training automatically. After training, evaluate the model using the ML.EVALUATE function — look for an AUC-ROC above 0.75 as a baseline. If accuracy is low, check your feature quality and ensure both churned and retained users are represented in roughly equal proportions in the training data. Once the model is trained, it stays in BigQuery and you call it via SQL from your Cloud Function.

bigquery_model.sql
1-- Run in BigQuery console
2CREATE OR REPLACE MODEL `your_project.analytics.churn_model`
3OPTIONS(
4 model_type = 'logistic_reg',
5 input_label_cols = ['churned'],
6 auto_class_weights = TRUE
7) AS
8SELECT
9 daysSinceLastActive,
10 totalSessionsLast30Days,
11 featureUsageCount,
12 purchaseCount,
13 profileCompletionPercent,
14 churned
15FROM `your_project.analytics.user_features`
16WHERE exportedAt < TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY);
17
18-- Evaluate the model
19SELECT *
20FROM ML.EVALUATE(
21 MODEL `your_project.analytics.churn_model`,
22 (SELECT * FROM `your_project.analytics.user_features`
23 WHERE exportedAt >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY))
24);

Expected result: The BigQuery console shows the trained model in the `analytics` dataset with AUC-ROC and accuracy metrics.

4

Create a Cloud Function that scores users and writes results to Firestore

Create a Cloud Function named `scoreUserChurnRisk`. It runs daily via Cloud Scheduler. The function queries the current `userStats` for all active users, calls BigQuery ML's `ML.PREDICT` via a SQL query to get a churn probability for each user, and writes the score back to each user's document in Firestore as a `churnScore` (float, 0-1) and `churnScoreUpdatedAt` timestamp. Also compute a `purchaseProbability` field if you have a purchase prediction model. In FlutterFlow, read these fields from the user document to personalize the UI — show win-back offers when `churnScore > 0.7`, upsell prompts when `purchaseProbability > 0.6`.

functions/scoreChurn.js
1const { onSchedule } = require('firebase-functions/v2/scheduler');
2const { getFirestore } = require('firebase-admin/firestore');
3const { BigQuery } = require('@google-cloud/bigquery');
4
5exports.scoreUserChurnRisk = onSchedule('every 24 hours', async () => {
6 const db = getFirestore();
7 const bq = new BigQuery();
8
9 const query = `
10 SELECT
11 userId,
12 predicted_churned_probs[OFFSET(1)].prob AS churnProbability
13 FROM ML.PREDICT(
14 MODEL \`your_project.analytics.churn_model\`,
15 (
16 SELECT
17 userId,
18 daysSinceLastActive,
19 totalSessionsLast30Days,
20 featureUsageCount,
21 purchaseCount,
22 profileCompletionPercent
23 FROM \`your_project.analytics.user_features\`
24 WHERE exportedAt >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY)
25 )
26 )
27 `;
28
29 const [rows] = await bq.query(query);
30 const batch = db.batch();
31
32 rows.forEach((row) => {
33 const ref = db.collection('users').doc(row.userId);
34 batch.update(ref, {
35 churnScore: row.churnProbability,
36 churnScoreUpdatedAt: new Date(),
37 });
38 });
39
40 await batch.commit();
41 console.log(`Scored ${rows.length} users`);
42});

Expected result: The `users` Firestore collection shows `churnScore` and `churnScoreUpdatedAt` fields updated daily for all active users.

5

Trigger automated re-engagement flows based on churn score

Create a Firestore onUpdate Cloud Function triggered when a user document's `churnScore` changes. If the new score exceeds 0.7 (configurable) and the previous score was below that threshold, trigger a re-engagement action: send a push notification via Firebase Cloud Messaging (or email via SendGrid), create a Firestore document in a `reEngagementQueue` collection, or update a `showWinBackOffer` boolean on the user document. In FlutterFlow, read `showWinBackOffer` on app launch and conditionally display a personalized win-back offer screen or banner. This makes the ML predictions actionable in real time rather than just interesting numbers.

Expected result: Users crossing the 0.7 churn threshold receive a re-engagement notification. The FlutterFlow app shows a win-back offer on their next session.

Complete working example

bigquery_model.sql
1-- Step 1: Create training dataset with churned label
2CREATE OR REPLACE TABLE `your_project.analytics.training_data` AS
3SELECT
4 userId,
5 daysSinceLastActive,
6 totalSessionsLast30Days,
7 featureUsageCount,
8 purchaseCount,
9 profileCompletionPercent,
10 CASE WHEN daysSinceLastActive > 30 THEN 1 ELSE 0 END AS churned
11FROM `your_project.analytics.user_features`
12WHERE exportedAt < TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY);
13
14-- Step 2: Check class balance
15SELECT churned, COUNT(*) as count
16FROM `your_project.analytics.training_data`
17GROUP BY churned;
18
19-- Step 3: Train churn model
20CREATE OR REPLACE MODEL `your_project.analytics.churn_model`
21OPTIONS(
22 model_type = 'logistic_reg',
23 input_label_cols = ['churned'],
24 auto_class_weights = TRUE,
25 max_iterations = 50
26) AS
27SELECT
28 daysSinceLastActive,
29 totalSessionsLast30Days,
30 featureUsageCount,
31 purchaseCount,
32 profileCompletionPercent,
33 churned
34FROM `your_project.analytics.training_data`;
35
36-- Step 4: Evaluate model performance
37SELECT
38 precision,
39 recall,
40 f1_score,
41 roc_auc,
42 log_loss
43FROM ML.EVALUATE(
44 MODEL `your_project.analytics.churn_model`,
45 (
46 SELECT * FROM `your_project.analytics.training_data`
47 WHERE MOD(ABS(FARM_FINGERPRINT(userId)), 5) = 0
48 )
49);
50
51-- Step 5: Get feature importance
52SELECT *
53FROM ML.FEATURE_IMPORTANCE(MODEL `your_project.analytics.churn_model`)
54ORDER BY importance_weight DESC;
55
56-- Step 6: Predict churn probability for current users
57SELECT
58 userId,
59 predicted_churned_probs[OFFSET(1)].prob AS churnProbability,
60 CASE
61 WHEN predicted_churned_probs[OFFSET(1)].prob > 0.7 THEN 'high'
62 WHEN predicted_churned_probs[OFFSET(1)].prob > 0.4 THEN 'medium'
63 ELSE 'low'
64 END AS churnRisk
65FROM ML.PREDICT(
66 MODEL `your_project.analytics.churn_model`,
67 (
68 SELECT
69 userId,
70 daysSinceLastActive,
71 totalSessionsLast30Days,
72 featureUsageCount,
73 purchaseCount,
74 profileCompletionPercent
75 FROM `your_project.analytics.user_features`
76 WHERE exportedAt >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY)
77 )
78)
79ORDER BY churnProbability DESC;

Common mistakes

Why it's a problem: Training the churn model on only churned users without including retained users

How to avoid: Export all users — active and churned — to the BigQuery training table. Use `auto_class_weights = TRUE` to handle any imbalance between the two classes. Aim for at least 200 examples of each class before training.

Why it's a problem: Running ML prediction queries client-side or exposing the BigQuery dataset to the Flutter app directly

How to avoid: Always call BigQuery from a Cloud Function. The Cloud Function uses the Firebase project's default service account, which can be granted BigQuery Data Viewer access from the Google Cloud IAM console without any credentials in the app.

Why it's a problem: Scoring all users every hour instead of daily

How to avoid: Run the scoring Cloud Function once per day via Cloud Scheduler. This matches the natural granularity of daily behavioral features and keeps BigQuery costs minimal.

Best practices

  • Use `auto_class_weights = TRUE` in BigQuery ML to handle class imbalance between churned and retained users.
  • Start with 5 high-signal features rather than 50 — daysSinceLastActive alone explains most churn variance.
  • Evaluate model performance with AUC-ROC, not just accuracy — a model that predicts everyone as retained looks 90% accurate if 90% of users are retained.
  • Store ML scores in the user's Firestore document so FlutterFlow can read them like any other field without extra API calls.
  • Add a rate-limit on re-engagement triggers — never send two win-back messages within 14 days to the same user.
  • Monitor model drift monthly — retrain the model every 4 weeks as user behavior patterns change.
  • Log when a user who received a re-engagement message returns to the app, so you can measure the campaign's conversion rate.

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I have a BigQuery table `user_features` with columns: userId, daysSinceLastActive, totalSessionsLast30Days, featureUsageCount, purchaseCount, profileCompletionPercent, churned. I want to train a logistic regression model using BigQuery ML and then run daily predictions for all active users. Write the SQL to: (1) train the model with auto class weights, (2) evaluate it using a holdout set, (3) query predictions with a churn probability score and risk tier (high/medium/low) for each user. Also explain what AUC-ROC means and what value I should aim for.

FlutterFlow Prompt

I have a Firebase Cloud Function that queries BigQuery ML predictions and writes a `churnScore` field back to each user's Firestore document. I want to add a Firestore onUpdate trigger that fires when `churnScore` changes and sends a push notification via Firebase Cloud Messaging if the new score is above 0.7. Write the Cloud Function for the Firestore trigger including the FCM notification and a check that re-engagement was not already sent in the last 14 days.

Frequently asked questions

How many users do I need before machine learning churn prediction is useful?

You need at least 500 users with known outcomes (churned or retained) for a statistically meaningful model. With fewer than 200 examples per class, the model will overfit and its predictions on new users will be unreliable. For early-stage apps, use simpler rules (e.g., send a re-engagement email if a user has not opened the app in 14 days) until you have enough data for ML.

What is the difference between BigQuery ML and calling OpenAI or Anthropic for predictions?

BigQuery ML trains a custom statistical model on your own user data. It learns from your specific app's behavior patterns. Large language models like GPT-4 are general-purpose text AI — they cannot predict your users' churn without being shown your historical data. For tabular predictions (numbers like session counts and days since last active), BigQuery ML or Vertex AI AutoML are the right tools, not LLMs.

How much does BigQuery ML cost to train and run predictions?

BigQuery ML training uses the same pricing as BigQuery queries — $5 per TB processed. A table with 10,000 users and 10 features is tiny (under 10MB) — training costs pennies. Daily predictions for 10,000 users also cost under $0.01. The main cost driver is the daily Firestore batch write to update user documents — at $0.18 per 100,000 writes, 10,000 users costs $0.018/day.

Can I use ML to predict what feature a user will want next, not just churn?

Yes. This is next-action prediction. Train a multi-class classification model where the label is the next feature the user engaged with (e.g., 'settings', 'upload', 'share'). Use recent navigation history as features. The model output is a probability distribution over possible next actions. Use the highest-probability prediction to surface contextual prompts or reorder navigation elements.

What if my model's churn predictions are wrong for a specific user segment?

This is called model bias or segmentation error. Investigate by breaking down model performance by user cohort (new vs. old users, paid vs. free, mobile vs. web). If accuracy is low for a specific segment, train a separate model for that segment or add segment-specific features. You can also use the ML.FEATURE_IMPORTANCE function to identify which features drive predictions for different user groups.

Do I need to retrain the model after new users join the app?

Not immediately. A model trained on existing users can score new users from day one. However, retrain monthly to incorporate the behavior patterns of newer user cohorts, which may differ from early users. If you launch a new major feature or change your onboarding, retrain immediately since user behavior will shift significantly.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.