0
# Remote Config
1
2
Firebase Remote Config server-side template management for dynamic app configuration without requiring app updates. Enables A/B testing, feature flags, and runtime configuration management.
3
4
## Capabilities
5
6
### Server Template Management
7
8
Manage Remote Config templates on the server side with evaluation and configuration capabilities.
9
10
```python { .api }
11
class ServerTemplate:
12
"""Server-side Remote Config template management."""
13
14
def load(self):
15
"""
16
Load the current Remote Config template from Firebase.
17
18
This method fetches the latest template configuration from
19
the Firebase Remote Config service.
20
"""
21
22
def evaluate(self, context=None):
23
"""
24
Evaluate the template with optional context.
25
26
Args:
27
context: EvaluationContext instance for personalized config (optional)
28
29
Returns:
30
ServerConfig: Evaluated configuration values
31
"""
32
33
def set(self, template_data_json):
34
"""
35
Set the Remote Config template data.
36
37
Args:
38
template_data_json: JSON string representing the template configuration
39
"""
40
41
class ServerConfig:
42
"""Evaluated Remote Config results."""
43
44
def get_value(self, key):
45
"""
46
Get a configuration value by key.
47
48
Args:
49
key: Configuration parameter key string
50
51
Returns:
52
Value: Configuration value with metadata
53
"""
54
55
def get_boolean(self, key):
56
"""
57
Get a boolean configuration value.
58
59
Args:
60
key: Configuration parameter key string
61
62
Returns:
63
bool: Boolean value of the parameter
64
"""
65
66
def get_number(self, key):
67
"""
68
Get a numeric configuration value.
69
70
Args:
71
key: Configuration parameter key string
72
73
Returns:
74
float: Numeric value of the parameter
75
"""
76
77
def get_string(self, key):
78
"""
79
Get a string configuration value.
80
81
Args:
82
key: Configuration parameter key string
83
84
Returns:
85
str: String value of the parameter
86
"""
87
```
88
89
## Configuration Management
90
91
### Template Structure
92
93
Remote Config templates define parameters with default values and conditional rules:
94
95
```json
96
{
97
"parameters": {
98
"welcome_message": {
99
"defaultValue": {
100
"value": "Welcome to our app!"
101
},
102
"conditionalValues": {
103
"premium_users": {
104
"value": "Welcome back, premium user!"
105
}
106
}
107
},
108
"feature_enabled": {
109
"defaultValue": {
110
"value": "false"
111
},
112
"conditionalValues": {
113
"beta_group": {
114
"value": "true"
115
}
116
}
117
},
118
"max_items": {
119
"defaultValue": {
120
"value": "10"
121
}
122
}
123
},
124
"conditions": [
125
{
126
"name": "premium_users",
127
"expression": "user.subscription == 'premium'"
128
},
129
{
130
"name": "beta_group",
131
"expression": "user.inRandomPercentile <= 10"
132
}
133
],
134
"parameterGroups": {},
135
"version": {
136
"versionNumber": "42",
137
"updateTime": "2024-01-15T10:30:00Z",
138
"updateUser": "admin@example.com",
139
"updateOrigin": "ADMIN_SDK_PYTHON"
140
}
141
}
142
```
143
144
### Evaluation Context
145
146
```python { .api }
147
class EvaluationContext:
148
"""Context for evaluating Remote Config conditions."""
149
150
def __init__(self, user_properties=None):
151
"""
152
Initialize evaluation context.
153
154
Args:
155
user_properties: Dict of user properties for condition evaluation
156
"""
157
158
class Value:
159
"""Remote Config parameter value with metadata."""
160
161
@property
162
def value(self):
163
"""The parameter value as string."""
164
165
@property
166
def source(self):
167
"""The source of this value (DEFAULT, REMOTE, etc.)."""
168
```
169
170
## Usage Examples
171
172
### Basic Template Management
173
174
```python
175
from firebase_admin import remote_config
176
177
# Create server template instance
178
template = remote_config.ServerTemplate()
179
180
# Load current template from Firebase
181
template.load()
182
183
# Evaluate configuration for a user
184
context = remote_config.EvaluationContext({
185
'user_id': 'user123',
186
'subscription': 'premium',
187
'app_version': '2.1.0'
188
})
189
190
config = template.evaluate(context)
191
192
# Get configuration values
193
welcome_message = config.get_string('welcome_message')
194
feature_enabled = config.get_boolean('feature_enabled')
195
max_items = config.get_number('max_items')
196
197
print(f'Welcome: {welcome_message}')
198
print(f'Feature enabled: {feature_enabled}')
199
print(f'Max items: {max_items}')
200
```
201
202
### Template Configuration
203
204
```python
205
import json
206
from firebase_admin import remote_config
207
208
# Define template configuration
209
template_config = {
210
"parameters": {
211
"app_theme": {
212
"defaultValue": {
213
"value": "light"
214
},
215
"conditionalValues": {
216
"dark_mode_users": {
217
"value": "dark"
218
}
219
}
220
},
221
"api_timeout": {
222
"defaultValue": {
223
"value": "30"
224
},
225
"conditionalValues": {
226
"slow_connection": {
227
"value": "60"
228
}
229
}
230
},
231
"new_feature_rollout": {
232
"defaultValue": {
233
"value": "false"
234
},
235
"conditionalValues": {
236
"feature_rollout_10_percent": {
237
"value": "true"
238
}
239
}
240
}
241
},
242
"conditions": [
243
{
244
"name": "dark_mode_users",
245
"expression": "user.preferences.theme == 'dark'"
246
},
247
{
248
"name": "slow_connection",
249
"expression": "user.connectionType == 'slow'"
250
},
251
{
252
"name": "feature_rollout_10_percent",
253
"expression": "user.inRandomPercentile <= 10"
254
}
255
]
256
}
257
258
# Set template configuration
259
template = remote_config.ServerTemplate()
260
template.set(json.dumps(template_config))
261
```
262
263
### Conditional Evaluation
264
265
```python
266
# Evaluate for different user contexts
267
users = [
268
{
269
'user_id': 'user1',
270
'preferences': {'theme': 'dark'},
271
'connectionType': 'fast',
272
'inRandomPercentile': 5
273
},
274
{
275
'user_id': 'user2',
276
'preferences': {'theme': 'light'},
277
'connectionType': 'slow',
278
'inRandomPercentile': 25
279
},
280
{
281
'user_id': 'user3',
282
'preferences': {'theme': 'light'},
283
'connectionType': 'fast',
284
'inRandomPercentile': 95
285
}
286
]
287
288
template = remote_config.ServerTemplate()
289
template.load()
290
291
for user in users:
292
context = remote_config.EvaluationContext(user)
293
config = template.evaluate(context)
294
295
theme = config.get_string('app_theme')
296
timeout = config.get_number('api_timeout')
297
new_feature = config.get_boolean('new_feature_rollout')
298
299
print(f'User {user["user_id"]}:')
300
print(f' Theme: {theme}')
301
print(f' Timeout: {timeout}s')
302
print(f' New feature: {new_feature}')
303
print()
304
```
305
306
### A/B Testing Configuration
307
308
```python
309
# Configure A/B test parameters
310
ab_test_config = {
311
"parameters": {
312
"button_color": {
313
"defaultValue": {
314
"value": "blue"
315
},
316
"conditionalValues": {
317
"variant_a": {
318
"value": "green"
319
},
320
"variant_b": {
321
"value": "red"
322
}
323
}
324
},
325
"checkout_flow": {
326
"defaultValue": {
327
"value": "standard"
328
},
329
"conditionalValues": {
330
"variant_a": {
331
"value": "simplified"
332
},
333
"variant_b": {
334
"value": "express"
335
}
336
}
337
}
338
},
339
"conditions": [
340
{
341
"name": "variant_a",
342
"expression": "user.experimentGroup == 'A'"
343
},
344
{
345
"name": "variant_b",
346
"expression": "user.experimentGroup == 'B'"
347
}
348
]
349
}
350
351
template = remote_config.ServerTemplate()
352
template.set(json.dumps(ab_test_config))
353
354
# Evaluate for A/B test participants
355
test_users = [
356
{'user_id': 'user1', 'experimentGroup': 'A'},
357
{'user_id': 'user2', 'experimentGroup': 'B'},
358
{'user_id': 'user3', 'experimentGroup': 'control'}
359
]
360
361
for user in test_users:
362
context = remote_config.EvaluationContext(user)
363
config = template.evaluate(context)
364
365
button_color = config.get_string('button_color')
366
checkout_flow = config.get_string('checkout_flow')
367
368
print(f'User {user["user_id"]} (Group {user["experimentGroup"]}):')
369
print(f' Button color: {button_color}')
370
print(f' Checkout flow: {checkout_flow}')
371
```
372
373
### Feature Flag Management
374
375
```python
376
# Feature flag configuration
377
feature_flags_config = {
378
"parameters": {
379
"payment_methods_v2": {
380
"defaultValue": {
381
"value": "false"
382
},
383
"conditionalValues": {
384
"beta_testers": {
385
"value": "true"
386
},
387
"gradual_rollout": {
388
"value": "true"
389
}
390
}
391
},
392
"analytics_enhanced": {
393
"defaultValue": {
394
"value": "false"
395
},
396
"conditionalValues": {
397
"premium_tier": {
398
"value": "true"
399
}
400
}
401
}
402
},
403
"conditions": [
404
{
405
"name": "beta_testers",
406
"expression": "user.role == 'beta_tester'"
407
},
408
{
409
"name": "gradual_rollout",
410
"expression": "user.inRandomPercentile <= 25"
411
},
412
{
413
"name": "premium_tier",
414
"expression": "user.subscription in ['premium', 'enterprise']"
415
}
416
]
417
}
418
419
template = remote_config.ServerTemplate()
420
template.set(json.dumps(feature_flags_config))
421
422
# Check feature availability for users
423
def check_features_for_user(user_data):
424
context = remote_config.EvaluationContext(user_data)
425
config = template.evaluate(context)
426
427
return {
428
'payment_v2': config.get_boolean('payment_methods_v2'),
429
'enhanced_analytics': config.get_boolean('analytics_enhanced')
430
}
431
432
# Example user checks
433
users = [
434
{'user_id': 'beta1', 'role': 'beta_tester', 'subscription': 'free'},
435
{'user_id': 'premium1', 'role': 'user', 'subscription': 'premium'},
436
{'user_id': 'regular1', 'role': 'user', 'subscription': 'free', 'inRandomPercentile': 15}
437
]
438
439
for user in users:
440
features = check_features_for_user(user)
441
print(f'User {user["user_id"]} features: {features}')
442
```
443
444
### Value Source Tracking
445
446
```python
447
# Track configuration value sources
448
template = remote_config.ServerTemplate()
449
template.load()
450
451
context = remote_config.EvaluationContext({
452
'user_id': 'user123',
453
'subscription': 'premium'
454
})
455
456
config = template.evaluate(context)
457
458
# Get value with source information
459
welcome_value = config.get_value('welcome_message')
460
print(f'Welcome message: {welcome_value.value}')
461
print(f'Source: {welcome_value.source}')
462
463
feature_value = config.get_value('feature_enabled')
464
print(f'Feature enabled: {feature_value.value}')
465
print(f'Source: {feature_value.source}')
466
```
467
468
## Advanced Condition Expressions
469
470
Remote Config supports complex condition expressions for sophisticated targeting:
471
472
### User Property Conditions
473
474
```python
475
# Examples of condition expressions:
476
conditions = [
477
# User demographics
478
"user.age >= 18 && user.age <= 65",
479
"user.country in ['US', 'CA', 'UK']",
480
"user.language == 'en'",
481
482
# App context
483
"app.version >= '2.0.0'",
484
"device.os == 'iOS'",
485
"device.model in ['iPhone12', 'iPhone13']",
486
487
# Behavioral targeting
488
"user.sessionCount >= 5",
489
"user.purchaseHistory.total > 100",
490
"user.lastActiveDate > '2024-01-01'",
491
492
# Time-based conditions
493
"percent <= 10", # 10% rollout
494
"user.inRandomPercentile <= 25", # 25% of users
495
496
# Combined conditions
497
"user.subscription == 'premium' && user.country == 'US'",
498
"(user.age >= 18 && user.age <= 25) || user.role == 'student'"
499
]
500
```
501
502
## Best Practices
503
504
### Configuration Design
505
506
- **Default Values**: Always provide sensible default values
507
- **Gradual Rollouts**: Use percentage-based conditions for feature rollouts
508
- **Documentation**: Document parameter purposes and expected values
509
- **Testing**: Test condition expressions thoroughly before deployment
510
511
### Performance Optimization
512
513
- **Caching**: Cache evaluated configurations to reduce computation
514
- **Batch Evaluation**: Evaluate multiple parameters in single calls
515
- **Minimal Context**: Include only necessary user properties in context
516
- **Template Versioning**: Track template changes for rollback capability
517
518
### Security and Privacy
519
520
- **Data Minimization**: Include only necessary user data in evaluation context
521
- **Access Control**: Restrict template modification permissions
522
- **Audit Logging**: Log configuration changes and access patterns
523
- **PII Handling**: Avoid including personally identifiable information
524
525
## Integration Patterns
526
527
### Server-Side Configuration Service
528
529
```python
530
class ConfigService:
531
def __init__(self):
532
self.template = remote_config.ServerTemplate()
533
self.template.load()
534
535
def get_user_config(self, user_data):
536
context = remote_config.EvaluationContext(user_data)
537
return self.template.evaluate(context)
538
539
def refresh_template(self):
540
"""Refresh template from Firebase (call periodically)"""
541
self.template.load()
542
543
# Usage in web application
544
config_service = ConfigService()
545
546
def handle_user_request(user_id, user_properties):
547
config = config_service.get_user_config(user_properties)
548
549
# Use configuration in application logic
550
theme = config.get_string('app_theme')
551
timeout = config.get_number('api_timeout')
552
553
return render_response(theme=theme, timeout=timeout)
554
```
555
556
## Types
557
558
```python { .api }
559
class ServerTemplate:
560
"""Server-side Remote Config template management."""
561
562
def load(self):
563
"""Load the current template from Firebase."""
564
565
def evaluate(self, context=None):
566
"""Evaluate template with context."""
567
568
def set(self, template_data_json):
569
"""Set template configuration."""
570
571
class ServerConfig:
572
"""Evaluated Remote Config results."""
573
574
def get_value(self, key):
575
"""Get configuration value with metadata."""
576
577
def get_boolean(self, key):
578
"""Get boolean configuration value."""
579
580
def get_number(self, key):
581
"""Get numeric configuration value."""
582
583
def get_string(self, key):
584
"""Get string configuration value."""
585
586
class EvaluationContext:
587
"""Context for evaluating Remote Config conditions."""
588
589
def __init__(self, user_properties=None):
590
"""Initialize with user properties dict."""
591
592
class Value:
593
"""Remote Config parameter value with metadata."""
594
595
@property
596
def value(self):
597
"""The parameter value as string."""
598
599
@property
600
def source(self):
601
"""The source of this value."""
602
```