firebase_rs_sdk/auth/
token_provider.rs

1use std::sync::atomic::{AtomicBool, Ordering};
2use std::sync::Arc;
3
4use crate::auth::error::AuthError;
5use crate::auth::Auth;
6use crate::firestore::error::{
7    internal_error, unauthenticated, unavailable, FirestoreError, FirestoreResult,
8};
9use crate::firestore::remote::datastore::{TokenProvider, TokenProviderArc};
10
11pub struct AuthTokenProvider {
12    auth: Arc<Auth>,
13    force_refresh: AtomicBool,
14}
15
16impl AuthTokenProvider {
17    /// Creates a Firestore-compatible token provider backed by Firebase Auth.
18    pub fn new(auth: Arc<Auth>) -> Self {
19        Self {
20            auth,
21            force_refresh: AtomicBool::new(false),
22        }
23    }
24
25    /// Converts the provider into an `Arc` for Datastore integration.
26    pub fn into_arc(self) -> TokenProviderArc {
27        Arc::new(self)
28    }
29}
30
31impl Clone for AuthTokenProvider {
32    fn clone(&self) -> Self {
33        Self {
34            auth: self.auth.clone(),
35            force_refresh: AtomicBool::new(self.force_refresh.load(Ordering::SeqCst)),
36        }
37    }
38}
39
40impl TokenProvider for AuthTokenProvider {
41    fn get_token(&self) -> FirestoreResult<Option<String>> {
42        let force_refresh = self.force_refresh.swap(false, Ordering::SeqCst);
43        self.auth.get_token(force_refresh).map_err(map_auth_error)
44    }
45
46    fn invalidate_token(&self) {
47        self.force_refresh.store(true, Ordering::SeqCst);
48    }
49}
50
51fn map_auth_error(error: AuthError) -> FirestoreError {
52    match error {
53        AuthError::InvalidCredential(message) => unauthenticated(message),
54        AuthError::Network(message) => unavailable(message),
55        AuthError::Firebase(firebase_error) => unauthenticated(firebase_error.message),
56        AuthError::App(app_error) => internal_error(app_error.to_string()),
57        AuthError::NotImplemented(feature) => {
58            internal_error(format!("{feature} is not implemented"))
59        }
60    }
61}
62
63/// Convenience helper that wraps an `Auth` instance into a token provider arc.
64pub fn auth_token_provider_arc(auth: Arc<Auth>) -> TokenProviderArc {
65    AuthTokenProvider::new(auth).into_arc()
66}