Skip to main content

firebase_admin_sdk/auth/
models.rs

1//! Data models for Firebase Authentication.
2
3use serde::{Deserialize, Serialize};
4
5/// Represents a user in the Firebase project.
6#[derive(Debug, Serialize, Deserialize, Default)]
7#[serde(rename_all = "camelCase")]
8pub struct UserRecord {
9    /// The user's unique ID.
10    pub local_id: String,
11    /// The user's email address.
12    pub email: Option<String>,
13    /// Whether the user's email has been verified.
14    pub email_verified: bool,
15    /// The user's display name.
16    pub display_name: Option<String>,
17    /// The user's photo URL.
18    pub photo_url: Option<String>,
19    /// The user's phone number.
20    pub phone_number: Option<String>,
21    /// Whether the user is disabled.
22    #[serde(default)]
23    pub disabled: bool,
24    /// Additional metadata about the user.
25    pub metadata: Option<UserMetadata>,
26    /// Information about the user's providers (Google, Facebook, etc.).
27    pub provider_user_info: Option<Vec<ProviderUserInfo>>,
28    /// The user's password hash.
29    pub password_hash: Option<String>,
30    /// The user's password salt.
31    pub password_salt: Option<String>,
32    /// Custom claims set on the user (JSON string).
33    pub custom_attributes: Option<String>,
34    /// The user's tenant ID (for multi-tenancy).
35    pub tenant_id: Option<String>,
36    /// Multi-factor authentication info.
37    pub mfa_info: Option<Vec<MfaInfo>>,
38}
39
40/// Metadata associated with a user account.
41#[derive(Debug, Serialize, Deserialize, Default)]
42#[serde(rename_all = "camelCase")]
43pub struct UserMetadata {
44    /// The date and time the user last signed in.
45    pub last_sign_in_time: Option<String>,
46    /// The date and time the account was created.
47    pub creation_time: Option<String>,
48    /// The date and time the user last refreshed their token.
49    pub last_refresh_time: Option<String>,
50}
51
52/// Information about a user's identity provider.
53#[derive(Debug, Serialize, Deserialize, Default)]
54#[serde(rename_all = "camelCase")]
55pub struct ProviderUserInfo {
56    /// The ID of the identity provider (e.g., google.com).
57    pub provider_id: String,
58    /// The user's display name linked to this provider.
59    pub display_name: Option<String>,
60    /// The user's photo URL linked to this provider.
61    pub photo_url: Option<String>,
62    /// The user's federated ID.
63    pub federated_id: Option<String>,
64    /// The user's email linked to this provider.
65    pub email: Option<String>,
66    /// The user's raw ID.
67    pub raw_id: Option<String>,
68    /// The user's screen name.
69    pub screen_name: Option<String>,
70}
71
72/// Multi-factor authentication information.
73#[derive(Debug, Serialize, Deserialize, Default)]
74#[serde(rename_all = "camelCase")]
75pub struct MfaInfo {
76    /// The MFA enrollment ID.
77    pub mfa_enrollment_id: Option<String>,
78    /// The display name for this MFA method.
79    pub display_name: Option<String>,
80    /// The phone number info for this MFA method.
81    pub phone_info: Option<String>,
82    /// The date and time this MFA method was enrolled.
83    pub enrolled_at: Option<String>,
84}
85
86/// Request to create a new user.
87#[derive(Debug, Serialize, Default)]
88#[serde(rename_all = "camelCase")]
89pub struct CreateUserRequest {
90    /// The UID to assign to the new user. If not provided, one will be generated.
91    #[serde(skip_serializing_if = "Option::is_none")]
92    pub local_id: Option<String>,
93    /// The user's email address.
94    #[serde(skip_serializing_if = "Option::is_none")]
95    pub email: Option<String>,
96    /// Whether the user's email is verified.
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub email_verified: Option<bool>,
99    /// The user's password.
100    #[serde(skip_serializing_if = "Option::is_none")]
101    pub password: Option<String>,
102    /// The user's display name.
103    #[serde(skip_serializing_if = "Option::is_none")]
104    pub display_name: Option<String>,
105    /// The user's photo URL.
106    #[serde(skip_serializing_if = "Option::is_none")]
107    pub photo_url: Option<String>,
108    /// Whether the user is disabled.
109    #[serde(skip_serializing_if = "Option::is_none")]
110    pub disabled: Option<bool>,
111    /// The user's phone number.
112    #[serde(skip_serializing_if = "Option::is_none")]
113    pub phone_number: Option<String>,
114}
115
116/// Request to update an existing user.
117#[derive(Debug, Serialize, Default)]
118#[serde(rename_all = "camelCase")]
119pub struct UpdateUserRequest {
120    /// The UID of the user to update.
121    pub local_id: String,
122    /// The new email address.
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub email: Option<String>,
125    /// The new email verification status.
126    #[serde(skip_serializing_if = "Option::is_none")]
127    pub email_verified: Option<bool>,
128    /// The new password.
129    #[serde(skip_serializing_if = "Option::is_none")]
130    pub password: Option<String>,
131    /// The new display name.
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub display_name: Option<String>,
134    /// The new photo URL.
135    #[serde(skip_serializing_if = "Option::is_none")]
136    pub photo_url: Option<String>,
137    /// The new disabled status.
138    #[serde(skip_serializing_if = "Option::is_none")]
139    pub disabled: Option<bool>,
140    /// The new phone number.
141    #[serde(skip_serializing_if = "Option::is_none")]
142    pub phone_number: Option<String>,
143    /// The new custom claims (JSON string).
144    #[serde(skip_serializing_if = "Option::is_none")]
145    pub custom_attributes: Option<String>,
146    /// Force token expiration (set validSince to now).
147    #[serde(skip_serializing_if = "Option::is_none")]
148    pub valid_since: Option<String>,
149    /// List of attributes to delete.
150    #[serde(skip_serializing_if = "Option::is_none")]
151    pub delete_attribute: Option<Vec<String>>,
152    /// List of providers to unlink.
153    #[serde(skip_serializing_if = "Option::is_none")]
154    pub delete_provider: Option<Vec<String>>,
155}
156
157/// Response from listing users.
158#[derive(Debug, Deserialize)]
159#[serde(rename_all = "camelCase")]
160pub struct ListUsersResponse {
161    /// The list of users.
162    pub users: Option<Vec<UserRecord>>,
163    /// The token for the next page of results.
164    pub next_page_token: Option<String>,
165}
166
167/// Internal request to get account info.
168#[derive(Debug, Serialize)]
169#[serde(rename_all = "camelCase")]
170pub struct GetAccountInfoRequest {
171    #[serde(skip_serializing_if = "Option::is_none")]
172    pub local_id: Option<Vec<String>>,
173    #[serde(skip_serializing_if = "Option::is_none")]
174    pub email: Option<Vec<String>>,
175    #[serde(skip_serializing_if = "Option::is_none")]
176    pub phone_number: Option<Vec<String>>,
177}
178
179/// Internal response from getting account info.
180#[derive(Debug, Deserialize)]
181#[serde(rename_all = "camelCase")]
182pub struct GetAccountInfoResponse {
183    pub users: Option<Vec<UserRecord>>,
184}
185
186/// Internal request to delete an account.
187#[derive(Debug, Serialize)]
188#[serde(rename_all = "camelCase")]
189pub struct DeleteAccountRequest {
190    pub local_id: String,
191}
192
193/// Internal request for email actions.
194#[derive(Debug, Serialize, Default)]
195#[serde(rename_all = "camelCase")]
196pub struct EmailLinkRequest {
197    pub request_type: String,
198    #[serde(skip_serializing_if = "Option::is_none")]
199    pub email: Option<String>,
200    #[serde(skip_serializing_if = "Option::is_none")]
201    pub continue_url: Option<String>,
202    #[serde(skip_serializing_if = "Option::is_none")]
203    pub can_handle_code_in_app: Option<bool>,
204    #[serde(skip_serializing_if = "Option::is_none")]
205    pub dynamic_link_domain: Option<String>,
206    #[serde(skip_serializing_if = "Option::is_none")]
207    pub android_package_name: Option<String>,
208    #[serde(skip_serializing_if = "Option::is_none")]
209    pub android_minimum_version: Option<String>,
210    #[serde(skip_serializing_if = "Option::is_none")]
211    pub android_install_app: Option<bool>,
212    #[serde(rename = "iOSBundleId", skip_serializing_if = "Option::is_none")]
213    pub ios_bundle_id: Option<String>,
214}
215
216/// Internal response for email actions.
217#[derive(Debug, Deserialize)]
218#[serde(rename_all = "camelCase")]
219pub struct EmailLinkResponse {
220    pub email: Option<String>,
221    pub oob_link: String,
222}
223
224/// A user record used for bulk import.
225#[derive(Debug, Serialize, Default)]
226#[serde(rename_all = "camelCase")]
227pub struct UserImportRecord {
228    /// The user's UID.
229    pub local_id: String,
230    /// The user's email.
231    #[serde(skip_serializing_if = "Option::is_none")]
232    pub email: Option<String>,
233    /// Whether the user's email is verified.
234    #[serde(skip_serializing_if = "Option::is_none")]
235    pub email_verified: Option<bool>,
236    /// The user's password hash.
237    #[serde(skip_serializing_if = "Option::is_none")]
238    pub password_hash: Option<String>,
239    /// The user's password salt.
240    #[serde(skip_serializing_if = "Option::is_none")]
241    pub password_salt: Option<String>,
242    /// The user's display name.
243    #[serde(skip_serializing_if = "Option::is_none")]
244    pub display_name: Option<String>,
245    /// The user's photo URL.
246    #[serde(skip_serializing_if = "Option::is_none")]
247    pub photo_url: Option<String>,
248    /// Whether the user is disabled.
249    #[serde(skip_serializing_if = "Option::is_none")]
250    pub disabled: Option<bool>,
251    /// The user's phone number.
252    #[serde(skip_serializing_if = "Option::is_none")]
253    pub phone_number: Option<String>,
254    /// The user's custom claims (JSON string).
255    #[serde(skip_serializing_if = "Option::is_none")]
256    pub custom_attributes: Option<String>,
257}
258
259/// Request to import users in bulk.
260#[derive(Debug, Serialize)]
261#[serde(rename_all = "camelCase")]
262pub struct ImportUsersRequest {
263    /// The list of users to import.
264    pub users: Vec<UserImportRecord>,
265    /// The hashing algorithm used for passwords (if any).
266    #[serde(skip_serializing_if = "Option::is_none")]
267    pub hash: Option<UserImportHash>,
268}
269
270/// Password hashing configuration for user import.
271#[derive(Debug, Serialize)]
272#[serde(rename_all = "camelCase")]
273pub struct UserImportHash {
274    /// The hashing algorithm (e.g., "SCRYPT").
275    pub hash_algorithm: String,
276    /// The signing key (base64 encoded).
277    pub key: String,
278    /// The salt separator (base64 encoded).
279    pub salt_separator: String,
280    /// The number of rounds.
281    pub rounds: i32,
282    /// The memory cost.
283    pub memory_cost: i32,
284}
285
286/// Response from user import.
287#[derive(Debug, Deserialize)]
288#[serde(rename_all = "camelCase")]
289pub struct ImportUsersResponse {
290    /// List of errors encountered during import.
291    pub error: Option<Vec<ImportUserError>>,
292}
293
294/// Error detail for a failed user import.
295#[derive(Debug, Deserialize)]
296#[serde(rename_all = "camelCase")]
297pub struct ImportUserError {
298    /// The index of the user in the request list.
299    pub index: usize,
300    /// The error message.
301    pub message: String,
302}
303
304/// Request to create a session cookie.
305#[derive(Debug, Serialize)]
306#[serde(rename_all = "camelCase")]
307pub struct CreateSessionCookieRequest {
308    /// The ID token to exchange for a session cookie.
309    pub id_token: String,
310    /// The number of seconds until the session cookie expires.
311    #[serde(rename = "validDuration")]
312    pub valid_duration_seconds: u64,
313}
314
315/// Response from creating a session cookie.
316#[derive(Debug, Deserialize)]
317#[serde(rename_all = "camelCase")]
318pub struct CreateSessionCookieResponse {
319    /// The created session cookie.
320    pub session_cookie: String,
321}
322
323// --- Action Code Settings ---
324
325/// Settings for generating email action links.
326#[derive(Debug, Serialize, Deserialize, Default, Clone)]
327#[serde(rename_all = "camelCase")]
328pub struct ActionCodeSettings {
329    /// The URL to continue to after the user clicks the link.
330    pub url: String,
331    /// Whether to open the link via a mobile app if installed.
332    #[serde(skip_serializing_if = "Option::is_none")]
333    pub handle_code_in_app: Option<bool>,
334    /// iOS specific settings.
335    #[serde(rename = "iOS", skip_serializing_if = "Option::is_none")]
336    pub ios: Option<IosSettings>,
337    /// Android specific settings.
338    #[serde(skip_serializing_if = "Option::is_none")]
339    pub android: Option<AndroidSettings>,
340    /// The dynamic link domain to use.
341    #[serde(skip_serializing_if = "Option::is_none")]
342    pub dynamic_link_domain: Option<String>,
343}
344
345/// iOS specific settings for action code.
346#[derive(Debug, Serialize, Deserialize, Default, Clone)]
347#[serde(rename_all = "camelCase")]
348pub struct IosSettings {
349    /// The iOS bundle ID.
350    pub bundle_id: String,
351}
352
353/// Android specific settings for action code.
354#[derive(Debug, Serialize, Deserialize, Default, Clone)]
355#[serde(rename_all = "camelCase")]
356pub struct AndroidSettings {
357    /// The Android package name.
358    pub package_name: String,
359    /// Whether to install the app if not already installed.
360    #[serde(skip_serializing_if = "Option::is_none")]
361    pub install_app: Option<bool>,
362    /// The minimum version of the app required.
363    #[serde(skip_serializing_if = "Option::is_none")]
364    pub minimum_version: Option<String>,
365}