firebase_rs_sdk/messaging/
support.rs1#[cfg(all(feature = "wasm-web", target_arch = "wasm32"))]
9use js_sys::Reflect;
10#[cfg(all(feature = "wasm-web", target_arch = "wasm32"))]
11use wasm_bindgen::{JsCast, JsValue};
12
13#[cfg(all(feature = "wasm-web", target_arch = "wasm32"))]
28pub fn is_supported() -> bool {
29 let window = match web_sys::window() {
30 Some(window) => window,
31 None => return false,
32 };
33 let navigator = window.navigator();
34 let navigator_js = JsValue::from(navigator.clone());
35
36 let cookie_enabled = Reflect::get(&navigator_js, &JsValue::from_str("cookieEnabled"))
37 .ok()
38 .and_then(|value| value.as_bool())
39 .unwrap_or(true);
40 if !cookie_enabled {
41 return false;
42 }
43
44 let service_worker_available = Reflect::get(&navigator_js, &JsValue::from_str("serviceWorker"))
45 .ok()
46 .map(|value| !value.is_undefined() && !value.is_null())
47 .unwrap_or(false);
48 if !service_worker_available {
49 return false;
50 }
51
52 match window.indexed_db() {
56 Ok(Some(_)) => {}
57 _ => return false,
58 }
59
60 let window_js = JsValue::from(window.clone());
61 if !property_in(&window_js, "PushManager")
62 || !property_in(&window_js, "Notification")
63 || !property_in(&window_js, "fetch")
64 {
65 return false;
66 }
67
68 if !prototype_has_property(&window_js, "ServiceWorkerRegistration", "showNotification") {
69 return false;
70 }
71
72 if !prototype_has_property(&window_js, "PushSubscription", "getKey") {
73 return false;
74 }
75
76 true
77}
78
79#[cfg(all(feature = "wasm-web", target_arch = "wasm32"))]
80fn property_in(target: &JsValue, property: &str) -> bool {
81 Reflect::has(target, &JsValue::from_str(property)).unwrap_or(false)
82}
83
84#[cfg(all(feature = "wasm-web", target_arch = "wasm32"))]
85fn prototype_has_property(target: &JsValue, constructor: &str, property: &str) -> bool {
86 let ctor = match Reflect::get(target, &JsValue::from_str(constructor)) {
87 Ok(value) => value,
88 Err(_) => return false,
89 };
90
91 let prototype = match Reflect::get(&ctor, &JsValue::from_str("prototype")) {
92 Ok(value) => value,
93 Err(_) => return false,
94 };
95
96 prototype
97 .dyn_ref::<js_sys::Object>()
98 .map(|obj| obj.has_own_property(&JsValue::from_str(property)))
99 .unwrap_or(false)
100}
101
102#[cfg(not(all(feature = "wasm-web", target_arch = "wasm32")))]
105pub fn is_supported() -> bool {
106 false
107}
108
109#[cfg(all(test, not(all(feature = "wasm-web", target_arch = "wasm32"))))]
110mod tests {
111 #[test]
112 fn non_wasm_targets_are_not_supported() {
113 assert!(!super::is_supported());
114 }
115}