How to refresh app when opened from deeplink? - firebase

I am struggling with a react native app. I would implement react native firebase dynamic link, but now I am a little lost. I use this method on HomeScreen which working perfectly every times when somebody opens the app.
async componentWillMount() {
try {
let url = await firebase.links().getInitialLink();
if(url) {
let api = "example.com/user/123456";
try {
this.setState({ data: "John Doe" });
this.props.navigation.navigate('Preview', {user: this.state.data })
}
catch {
}
}
}
catch {
}
}
But when the app is already opened this method doesn't work properly. Is there a way where I can trigger a function every time when somebody comes back to the opened app?

Just a tip, you should place your code in componentDidMount so that you do not block the initial (first) render.
You could use AppState to listen out for changes to apps being put in the background/foreground.
componentDidMount() {
this.showPreview();
AppState.addEventListener('change', this.onAppStateChange);
}
componentWillUnmount() {
AppState.removeEventListener('change', this.onAppStateChange);
}
const onAppStateChange = appState => {
// You can check if appState is active/background/foreground
this.showPreview();
}
const showPreview = async (appState) => {
// You can check if appState is active/inactive/background
try {
let url = await firebase.links().getInitialLink();
if(url) {
let api = "example.com/user/123456";
try {
this.setState({ data: "John Doe" });
this.props.navigation.navigate('Preview', {user: this.state.data })
}
catch {
}
}
}
catch(e) {
console.error(e);
}
}

Related

Nuxt3 and Pinia: how to save async API data to the store

I created a Pinia store file to retrieve invoices information from the Node.js API I created available on a public API address
import { mande } from "mande";
import { acceptHMRUpdate, defineStore } from "pinia";
import { useUsersStore } from "./user";
const api = mande("http://xxx.xxx.xxx.xxx/"); // hiding the IP address
const usersStore = useUsersStore();
await usersStore.signIn("test#gmail.com", "password");
api.options.headers.Authorization = "Bearer " + usersStore.getAccessToken;
export const useInvoicesStore = defineStore("invoices", {
state: () => ({
invoices: <any>[] || [],
invoice: null,
loading: false,
}),
getters: {
getInvoices: (state) => state.invoices,
getInvoice: (state) => state.invoice,
},
actions: {
async fetchInvoices() {
this.invoices = [];
this.loading = true;
try {
this.invoices = (await api.get("invoices")) as any[];
} catch (error) {
console.log(error);
} finally {
this.loading = false;
}
},
async fetchInvoice(id: string) {
this.invoice = null;
this.loading = true;
try {
this.invoice = (await api.get(`invoices/${id}`)) as any;
} catch (error) {
console.log(error);
} finally {
this.loading = false;
}
},
async createInvoice(invoice: any) {
this.loading = true;
try {
await api.post("invoices", invoice);
} catch (error) {
console.log(error);
} finally {
this.loading = false;
}
},
async updateInvoice(id: string, invoice: any) {
this.loading = true;
try {
await api.patch(`invoices/${id}`, invoice);
} catch (error) {
console.log(error);
} finally {
this.loading = false;
}
},
},
});
if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useUsersStore, import.meta.hot));
}
I use the store in a Nuxt3 page
<script setup>
const store = useInvoicesStore();
definePageMeta({
layout: "app",
});
let invoices = [];
await store.fetchInvoices();
invoices = store.getInvoices;
</script>
<template>
<div>
<main>
{{ invoices }}
<div class="mx-auto max-w-7xl py-6 sm:px-6 lg:px-8">
<AppInvoiceList :invoices="invoices" />
</div>
</main>
</div>
</template>
I print the entire JSON (invoices) on the UI to understand whether the information is fetched from the server. What happens is that, once I hit reload (F5), for a split second the data appears on the screen. After that, the array is empty and the store as well.
How can I correctly save the data coming from the API in the Pinia store?
This is not the purpose of a Pinia store, it does not give out of the box persisted store states, it is only for providing central state management during the uninterrupted life span of the PWA.
There are two ways I can think of to persist the central state between reloads.
Option 1
Use $subscribe to save Pinia states to the browsers localStorage or indexDB using them as a cache, then on first load check localStorage for anything to restore back to the Pinia state else query the backend, you will need to consider a cache timeout mechanism.
https://pinia.vuejs.org/core-concepts/state.html#subscribing-to-the-state
There may be a persisted state pinia plugin available to do this for you, try searching for a solution.
Option 2
Service worker API - You may not need panini at all.
https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
https://developer.mozilla.org/en-US/docs/Web/API/Cache

How to get stripe customers in next js

I am using Stripe in my NextJs project and have tried to get customers list in my app but have not succeeded. If anyone knows how to get it, please instruct me on how to do that.
This is my code:
import { loadStripe } from "#stripe/stripe-js";
async function getStripeCustomers(){
const stripe = await loadStripe(
process.env.key
);
if (stripe) {
// there was a toturail for node.js like this.
console.log(stripe.customers.list())
}
}
useEffect(() => {
getStripeCustomers()
}, []);
I think you should do this logic in backend so create a route in api folder then try this code.
// api/payment/get-all-customers.js
import Stripe from "stripe";
export default async function handler(req, res) {
if (req.method === "POST") {
const { token } = JSON.parse(req.body);
if (!token) {
return res.status(403).json({ msg: "Forbidden" });
}
const stripe = new Stripe(process.env.NEXT_PUBLIC_STRIPE_SECRET, {
apiVersion: "2020-08-27",
});
try {
const customers = await stripe.customers.list(); // returns all customers sorted by createdDate
res.status(200).json(customers);
} catch (err) {
console.log(err);
res.status(500).json({ error: true });
}
}
}
Now from frontend send a POST request to newly created route.

How to create a reactive statement in Svelte with Firebase's onSnapshot?

I'm learning Svelte for the past 4 days and I'm trying to integrate it with Firebase.
I need to listen to a document named after the user's uid after the user logged in which I saved in a writable name userStore.
Note: My background was React and this can be done easily with useEffect
I need a way to call unsubscribe in the onDestroy statement... How can I do that?
onDestroy(() => {
unsubscribe();
});
This is my current code:
$: if ($userStore)
onSnapshot(doc(db, 'userInfo', $userStore.uid), (doc) => {
if (doc.data()) {
console.log(doc.data());
userInfoStore.set(doc.data() as UserInfo);
}
});
I think onSnapshot() returns unsubscribe, so it should work like this
<script>
let unsubscribe
onDestroy(() => {
if(unsubscribe) unsubscribe();
});
$: if ($userStore) {
unsubscribe = onSnapshot(doc(db, 'userInfo', $userStore.uid), (doc) => {
if (doc.data()) {
console.log(doc.data());
userInfoStore.set(doc.data() as UserInfo);
}
});
}
</script>
Is the component destroyed when the user logs out? Because the unsubcription should be called if the user logs out? I think in a component might not be the best place to handle the logic. This would be a way via a custom store
userInfoStore.js
export const userInfoStore = (() => {
const initialValue = {}
const {subscribe, set} = writable(initialValue)
let unsubSnapshot
return {
subscribe,
startListener(uid) {
unsubSnapshot = onSnapshot(doc(db, 'userInfo', uid), (doc) => {
if (doc.data()) {
console.log(doc.data());
set(doc.data() as UserInfo);
}
});
},
stopListener() {
if(unsubSnapshot) unsubSnapshot()
}
}
})();
auth.js
onAuthStateChanged(auth, user => {
if(user) {
userStore.set(user)
userInfoStore.startListener(user.uid)
}else {
userInfoStore.stopListener()
}
})
App.svelte (main component)
Don't know how important that is or if the listener is stopped anyway when the page is closed
<script>
import {onDestroy} from 'svelte'
import {userInfoStore} './userInfoStore'
onDestroy(() => {
userInfoStore.stopListener()
});
</script>

Protected Route With Firebase and Svelte

I'm trying to create a protected page, the profile page of my project. I want to throw people out if they are not logged in. I'm trying to do it as simply as possible. I find this tutorial, but is TypeScript and I couldn't get it to work. Link >
My way:
Profile page:
let auth = getAuth();
onMount(() => {
auth.onAuthStateChanged((user) => {
if (!user) {
goto('/signin');
}
});
});
The idea is to have a user store and use it with the combination of onAuthStateChanged
import authStore from '../stores/authStore';; // <~ stores.ts
import { onMount } from 'svelte';
let auth = getAuth();
onMount(() => {
//shift this method to a firebase.ts
auth.onAuthStateChanged((user) => {
if (user) {
authStore.set({
user,
});
} else {
authStore.set({
user: null,
});
}
});
});
// this block will watch changes on the store
$: {
if (!$authStore.user) {
if (browser) goto('/login');
} else {
if (browser) goto('/');
}
}

iOS 14.5 App Tracking Transparency for firebase logs in react-native app

Firebase logs stopped working as soon as updated to iOS 14.5 for one of the react-native app I am working on.
What are the necessary changes that we need to do to make it working again?
You need to request Tracking permissions first (I used react-native-permissions):
import { request, RESULTS, PERMISSIONS } from 'react-native-permissions'
import { Settings } from 'react-native-fbsdk-next'
export const requestPermissionTransparency = async () => {
return await request(PERMISSIONS.IOS.APP_TRACKING_TRANSPARENCY)
}
useEffect(() => {
;(async () => {
const result = await requestPermissionTransparency()
if (result === RESULTS.GRANTED) {
await firebase.analytics().setAnalyticsCollectionEnabled(true)
await Settings.setAdvertiserTrackingEnabled(true)
} else {
await firebase.analytics().setAnalyticsCollectionEnabled(false)
await Settings.setAdvertiserTrackingEnabled(false)
}
})()
}, [])
Remember to add this file in the root project:
// <project-root>/firebase.json
{
"react-native": {
"analytics_auto_collection_enabled": false
}
}
References: https://rnfirebase.io/analytics/usage

Resources