Quantcast
Channel: Ionic Framework - Ionic Forum
Viewing all 49234 articles
Browse latest View live

Edit Manifest at runtime

$
0
0

I integrated a capacitor plugin that use values defined into static Android Manifest for Android.

I need to set these values at runtime becaust they depends from business logic. How can I edit these value at runtime progrmamatically?

<meta-data android:name="customproperty" android:value="123" />

Thanks

1 post - 1 participant

Read full topic


React Navigation

$
0
0

Can we use modern react-router hooks like navigate() etc in ionic? Because in ionic framework docs, you are only talking about ancient navigation methods using the history prop.

Thanks

1 post - 1 participant

Read full topic

Ionic react framework support given that Create React App is now deprecated

$
0
0

Hi there,

Create React App for desktop and Ionic React worked perfectly fine and enabled us to use almost all of code with minimal change. However, the Create React App option is removed from the React documentation as the React team wants developers to pick a framework instead. However, Ionic still uses Create React App approach which makes it difficult to look forward as I am not sure how Ionic wants to handle this change.

What is the recommended way forward? Should we wait for ionic to start supporting a framework or not?

Thanks,

Douf

3 posts - 2 participants

Read full topic

How to Build a Dynamic Plugin System in Ionic Framework 8 with Vue.js?

$
0
0

How can I create a plugin system for my Ionic Framework 8 application using Vue.js?

I want to develop a marketplace of functionalities within my Ionic project, where each extension or plugin will be stored in a Git repository. When the user activates a plugin/extension, it should create a new item in the menu, generate pages, and offer the new functionality provided by the plugin/extension.

How can I achieve this using Ionic Framework 8 and Vue.js?

Any ideas or suggestions would be greatly appreciated!

1 post - 1 participant

Read full topic

Ionic vue running on device , the login work successfully but when it directed me to the dashboard , it didn't get the data from api and the user details

Badge enhancement for tabs

$
0
0

I want to propose an enhancement to tabs that would allow the use of badges to tabs for use in the ion-tabs component. One use case would be to show the count of new items in an ‘Inbox’ tab.
An example of 3 new properties for a tab:
showBadge: boolean
badgeValue: number
badgeColor: color

This enhancement would be rally helpful in providing a context for users that would guide them to look at a particular tab when there is something new.

1 post - 1 participant

Read full topic

Taylor Swift Joins Chiefs Kingdom, Confirmed?

Issues with Facebook auth

$
0
0

Seemingly at random, when I try to run a simulator of an iPhone 15, I have an issue where the build fails, and says that the architecture is unsupported. I haven’t had any issues before this point, but the build has started to consistently fail. Has anyone else had an issue like this?

Thanks!

1 post - 1 participant

Read full topic


Ionic6 ,On some Android phones, in the browser, open the page, click on the time in the on ion-datetime-button, and whether it is clicking on the hour or minute, it will jump up one by one until it shows 00. I don't know why

$
0
0

On some Android phones, in the browser, open the page, click on the time in the on ion-datetime-button, and whether it is clicking on the hour or minute, it will jump up one by one until it shows 00. I don’t know why
code:
```

    <ion-label floating>End Date</ion-label>
    <ion-datetime-button datetime="datetime2" ></ion-datetime-button>

    <ion-modal [keepContentsMounted]="true">
      <ng-template>
        <ion-datetime id="datetime2" formControlName="EndDate" (ionChange)="onDateChange($event)"></ion-datetime>
      </ng-template>
    </ion-modal>

1 post - 1 participant

Read full topic

Google SignIn on Android, error Code 10

$
0
0

I integrated Google Oauth Sign In in my Ionic Capacitor App but I have an issue for Android Device only:

When the user clicks on the Google login button from the app, a popup appears to select the gmail account. Immediately afterwards the system goes into error and in the log I find this error:

{
	"save": false,
	"callbackId": "21517523",
	"pluginId": "GoogleAuth",
	"methodName": "signIn",
	"success": false,
	"error": {
		"message": "Something went wrong",
		"code": "10"
	}
}

I’ve read several posts and tried different solutions but I can’t resolve the problem. I followed the following steps

  1. I deleted all fingerprints from Firebase Console for Android application

  2. I have deleted all references from Google Cloud Console Oauth 2.0 Client IDs for the Android application

  3. Generated SHA certificate fingerprint using windows shell command

keytool -keystore my-jks-file-path -list -v

Certificate fingerprints:
         SHA1: 56:5D:38:F2:D0:XX:XX:XX:XX:XX:D7:FB:56:7A:A2:D4:B5:1B:D0:C5
  1. Add SHA certificate fingerprint from Firebase Console (Android Apps)

  2. Google creae automatically reference into Google Cloud Console Oauth 2.0 Client IDs (Android client for (auto created by Google Service))

  3. Downloaded google-services.json file-path

  4. Copied google-services.json file into my ionic app into .\android\app\google-services.json

  5. Rebuild App using keystore (the same used for generate SHA certificate fingerprints )

  6. Installed on my android device

Please help me.
Thanks

1 post - 1 participant

Read full topic

ESLint not working with Ionic React 8 TypeScript project

$
0
0

I have a Ionic React 8 TypeScript project generated using the Ionic CLI. But executing npx eslint results in no warnings / errors. What am I missing?

3 posts - 3 participants

Read full topic

Not able to decrypt AES-256 in server side after encrypted in IONIC5

$
0
0

I am ecryptinga text in IONIC using @ionic-native/aes-256/ngx library and trying to decrypt the same in PHP but unable to do so.

Here’s the data : Key : 12345678901234567890123456789012 (32bit) IV : 1234567890123456 Plain Text : ABCD

Encrypted in IONIC : "W2/PbR8z0sKBblfd4ezO1DKI/7UrB/egwDEGyw7w9tY= "

But it’s decrypting in IONIC but not in PHP. In PHP i tried encryption of the same text using same keys but also I am getting different encrypted data. PHP encrypted data for string “ABCD” : “5JvCGZhhM12hA9Tz/ldBvw==”

Can somebody please explain if I am missing anything?

Encrypted data in IONIC and PHP are different. I want to decrypt the text in PHP which was done using IONIC

4 posts - 2 participants

Read full topic

Advantages of Using Ionic for Hybrid Mobile App Development?

$
0
0

Hello, I Manav Gangwani am new to Ionic and this community. What are the key advantages of using the Ionic framework for hybrid mobile app development, and how does it compare to other frameworks like React Native and Flutter?

Thanks in advance :slight_smile:

2 posts - 2 participants

Read full topic

Help Needed, @capacitor/browser, appurllistener

$
0
0

Hey so were building a decoupled checkout for a wordpress/woocommerce application i got the flow set-up and functional at this point but when the appurllisterner captures the url i echo from the complete checkout its redirecting me back to the cart page, i’ve turned import { Browser } from ‘@capacitor/browser’; into a hooke called useBrowserOpen.tsx which is what you’ll see in the code to ensure the browser listener opens and closes, but im not sure why its taking me to cart page before it goes to the link the appurllistener actual calls, i also see it the first execution in the console log before executing the remaining queries needed and then its called again which then redirects after the logic in the browser close runs, which is a query used to get the user jwt token based on if the user logged in from that page.


import { useHistory } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { App, URLOpenListenerEvent } from '@capacitor/app';
import { PluginResultData } from '@capacitor/core';
import { useDispatch } from 'react-redux';
import { resetCart } from '../store/cartSlice';
import useBrowserOpen from '../hooks/useBrowserOpen'; // Adjust the path to your hook

const createHandleAppUrlOpen = ({
	history,
	location,
}: {
	history: ReturnType<typeof useHistory>;
	location: typeof window.location;
}) => (data: PluginResultData) => {
	console.debug('[====AppUrlListener.tsx====][appUrlOpen] App opened with URL:', data);

	const checkDataForUrl = (data: PluginResultData): data is URLOpenListenerEvent => data.url !== undefined;

	if (!checkDataForUrl(data)) {
		console.debug('[====AppUrlListener.tsx====][appUrlOpen] Data does not include url property! Listener not triggered.');
		return;
	}

	const event = data;
	const hostname = location.hostname;

	if (!hostname || !event.url.includes(hostname)) return;

	const slug = event.url.split(hostname).pop();

	if (!slug) return;

	// const addCapacitorListeners = ({ history, location }: { history: ReturnType<typeof useHistory>, location: typeof window.location }) => {
	// 	const handleAppUrlOpen = createHandleAppUrlOpen({ history, location })
	//
	// 	App.addListener('appUrlOpen', handleAppUrlOpen)
	//
	// 	App.addListener('backButton', () => {
	// 		console.debug('[====AppUrlListener.tsx====][backButton] App back button pressed')
	// 	})
	// 	App.addListener('pause', () => {
	// 		console.debug('[====AppUrlListener.tsx====][pause] App paused')
	// 	})
	// 	App.addListener('resume', () => {
	// 		console.debug('[====AppUrlListener.tsx====][resume] App resumed')
	// 	})
	// 	App.addListener('appStateChange', ({ isActive }) => {
	// 		console.debug(`[====AppUrlListener.tsx====][appStateChange] App state changed to ${isActive ? 'ACTIVE' : 'NOT ACTIVE'}`)
	// 	})
	// 	App.addListener('appRestoredResult', data => {
	// 		console.debug('[====AppUrlListener.tsx====][appRestoredResult] Restored state:', data)
	// 	})
	// }

	history.push(slug);
};

const AppUrlListener: React.FC = () => {
	const history = useHistory();
	const location = window.location;
	const dispatch = useDispatch();
	const { closeBrowser } = useBrowserOpen('', async () => {}); // Adjust as needed for your use case

	const [processedUrls, setProcessedUrls] = useState<string[]>([]); // State to track processed URLs

	useEffect(() => {
		console.debug('[====AppUrlListener.tsx====][useEffect] component mounted', { history, location });

		const handleDeepLink = (url: string) => {
			if (processedUrls.includes(url)) {
				console.debug('[====AppUrlListener.tsx====] URL already processed:', url);
				return;
			}

			let path;
			const urlObject = new URL(url);

			if (url.startsWith('https:') || url.startsWith('http:')) {
				// Handle universal links (HTTP/HTTPS)
				path = urlObject.pathname;
			} else {
				// Handle custom URL schemes by extracting the path after the scheme
				const slug = url.split('://').pop();
				path = slug || '';
			}

			// Special handling for password reset links
			if (path.includes('wp-login.php')) {
				// Check if it's the password reset action
				const action = urlObject.searchParams.get('action');
				const key = urlObject.searchParams.get('key');
				const login = urlObject.searchParams.get('login');

				if (action === 'rp' && key && login) {
					// Redirect to the reset-password route with key and login
					history.push(`/reset-password/${key}/${encodeURIComponent(login)}`);
					console.log('Redirecting to reset-password:', key, login);
					setProcessedUrls([...processedUrls, url]); // Mark URL as processed
					return;
				}
			}

			// Normalize the path to remove any leading slashes
			if (path.startsWith('/')) {
				path = path.slice(1);
			}

			if (path.includes('order-confirmed')) {
				const orderId = urlObject.searchParams.get('order');
				const order_confirmation_path = '/order-confirmed/' + orderId;
				history.push(order_confirmation_path);
				setProcessedUrls([...processedUrls, url]); // Update processedUrls immediately
				closeBrowser();
				dispatch(resetCart());

				// Ensure navigation and operations happen sequentially
				// setTimeout(() => {
				// 	dispatch(resetCart());
				// 	closeBrowser();
				// }, 0);

				return;
			}

			// Combine path and query parameters to form the full path
			const fullPath = '/' + path + urlObject.search;
			console.debug('[====AppUrlListener.tsx====] Navigating to:', fullPath);
			history.push(fullPath); // Navigate using React Router
			setProcessedUrls([...processedUrls, url]); // Mark URL as processed
		};

		const handleAppUrlOpen = createHandleAppUrlOpen({ history, location });

		App.addListener('appUrlOpen', (event: URLOpenListenerEvent) => {
			console.debug('[====AppUrlListener.tsx====] Deep link URL received:', event.url);
			if (event.url.includes('wp-login.php') && event.url.includes('action=rp')) {
				// Handle the specific URL with 'wp-login.php' and 'action=rp'
				handleDeepLink(event.url);
			} else {
				// Handle other deep links using existing logic
				handleDeepLink(event.url);
			}
		});

		// Handle deep links on app start or cold start
		App.addListener('appRestoredResult', (data) => {
			console.debug('[====AppUrlListener.tsx====] App restored with result:', data);
			if (data.url) {
				handleDeepLink(data.url);
			}
		});

		// Cleanup listeners when the component is unmounted
		return () => {
			console.debug('[====AppUrlListener.tsx====] Component unmounted.');
			App.removeAllListeners();
		};
	}, [history, location, closeBrowser, dispatch, processedUrls]);

	return null;
};

export default AppUrlListener;


import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Browser } from '@capacitor/browser';
import {
	setJwtToken,
	setCustomer,
	setAuthTokenExpiration,
	setRefreshToken,
	setWooSessionToken,
	setRefreshTokenExpiration,
	updateCustomerId,
} from '../store/authSlice';
import { useQuery } from '@apollo/client';
import { GET_SESSION_DATA } from '../queries/authQueries';
import { getUserWithAuthData } from '../queries/authAPI';
import { RootState } from '../store/store';
import { decodeJwt, CustomJwtPayload } from "../utils/decodeJWT";
import { Customer } from '../store/authSlice'; // Ensure this is the correct import path

const useBrowserOpen = (checkoutUrl: string, updateSession: () => Promise<any>) => {
	const dispatch = useDispatch();
	const authState = useSelector((state: RootState) => state.auth);

	useEffect(() => {
		console.log("[log] - Current auth state: ", JSON.stringify(authState));
	}, [authState]);

	const { data: sessionData, error: sessionError, refetch: refetchSessionData } = useQuery(GET_SESSION_DATA);

	const handleBrowserFinished = async () => {
		try {
			await updateSession();

			const refetchResponse = await refetchSessionData(); // Fetch session data after updating
			// console.log("[log] - Refetch Response: ", refetchResponse);

			const jwtToken = refetchResponse.data?.guestSessionData;
			// console.log("[log] - JWT Token: ", jwtToken);

			if (jwtToken && jwtToken !== "Valid session token not found.") {
				dispatch(setJwtToken(jwtToken));
				// console.log("[log] - JWT Token set in Redux: ", jwtToken);

				const decodedToken: CustomJwtPayload | null = jwtToken ? decodeJwt(jwtToken) : null;
				// console.log("[log] - Decoded Token: ", decodedToken);

				if (decodedToken) {
					const customerId = decodedToken.data.user.id;
					const exp = decodedToken.exp;

					// console.log("[log] - Decoded Customer ID: ", customerId);
					// console.log("[log] - Decoded Expiration Time: ", exp);

					if (customerId) {
						dispatch(updateCustomerId(customerId));

						if (exp) {
							dispatch(setAuthTokenExpiration(exp * 1000)); // Convert exp to milliseconds
							// console.log("[log] - Token Expiration Time set in Redux: ", exp * 1000);
						} else {
							// console.warn("[warn] - Expiration time not found in JWT token");
						}

						// console.log("[log] - Fetching user data with customer ID: ", customerId);
						const userData = await getUserWithAuthData(customerId, "DATABASE_ID");
						// console.log("[log] - User data is: ", userData);

						if (userData) {
							const {
								email,
								firstName,
								lastName,
								databaseId,
								auth: {
									authToken,
									authTokenExpiration,
									refreshToken,
									refreshTokenExpiration,
									wooSessionToken,
								}
							} = userData;

							// Save the refresh token in the Redux store
							dispatch(setRefreshToken(refreshToken));

							// console.log("[log] - Constructing customer object with user data", userData);
							const customer: Customer = {
								firstName,
								lastName,
								email,
								databaseId,
								accountNonce: "",
								cartNonce: "",
								checkoutNonce: "",
								checkoutUrl: "",
								cartUrl: "",
								role: "",
								id: databaseId.toString(),
								birthYear: "",
								sunSign: "",
								phone: "",
								fcmToken: null,
								externalId: null,
								orders: { nodes: [] },
								shipping: {
									firstName,
									lastName,
									phone: "",
									postcode: "",
									state: "",
									email,
									city: "",
									address1: "",
									address2: "",
									country: ""
								},
								billing: undefined
							};

							// console.log("[log] - Customer object constructed: ", customer);
							// console.log("[log] - Dispatching customer data to Redux");

							dispatch(setCustomer(customer));
							dispatch(setJwtToken(authToken));
							dispatch(setRefreshToken(refreshToken));
							dispatch(setAuthTokenExpiration(Number(authTokenExpiration) * 1000)); // Convert exp to milliseconds
							dispatch(setRefreshTokenExpiration(Number(refreshTokenExpiration) * 1000));
							dispatch(setWooSessionToken(wooSessionToken));

							// console.log("[log] - User data refreshed and customer updated in Redux: ", customer);
							// console.log("authstate at the end :", authState);
						} else {
							console.error("[error] - User data not found or malformed", userData);
						}
					} else {
						console.error("[error] - Customer ID not found in JWT token");
					}
				} else {
					console.error("[error] - Error decoding JWT token, decodedToken is null");
				}
			} else {
				console.error("[error] - JWT token not found in GET_SESSION_DATA");
				return;
			}
		} catch (error) {
			console.log("[error] - Error updating customer state:", error);
		}
	};

	const openBrowser = async () => {
		// console.log("[log] - Attempting to open browser with URL: ", checkoutUrl);
		if (checkoutUrl) {
			await Browser.open({ url: checkoutUrl });
		} else {
			console.error("[error] - Checkout URL not set");
		}
	};

	const closeBrowser = async () => {
		// console.log("[log] - Attempting to close browser");
		await Browser.close();
	};

	const setListener = async () => {
		// console.log("[log] - Setting browser listeners");
		await Browser.removeAllListeners();
		await Browser.addListener('browserFinished', async () => {
			try {
				// console.log("[log] - browserFinished event received");
				await handleBrowserFinished();
				// console.log("[log] - browserFinished: Finished handleBrowserFinished");
			} catch (error) {
				// console.log("[error] - browserFinished: Error: ", error);
			}
		});
	};

	useEffect(() => {
		setListener();

		return () => {
			// console.log("[log] - Removing all browser listeners");
			handleBrowserFinished();
			Browser.removeAllListeners();
		};
	}, []);

	return { openBrowser, closeBrowser };
};

export default useBrowserOpen;

any help or direction is appreciated as im new to ionic and can potentially be doing something incorrectly.

1 post - 1 participant

Read full topic

Does Ionic React 8 Cache CSS Files

$
0
0

I am new to Ionic and React. I have created an Ionic React 8 project using the Ionic CLI. I have 2 pages which use their own CSS file with same CSS class names but different properties for the root level div. However, upon navigating to Page 2 from Page 1, Page 2 uses properties from Page 1 CSS file. Is this behaviour expected and if yes then how to fix this?

2 posts - 2 participants

Read full topic


Ionic loadingController Dismiss Issue | spinner Bug

$
0
0

In Ionic 5 , i am getting issue if we change tab while loading something or any api calling at the time i kept loadingController spinner after api call complete spinner will dismiss.

But in my case if API getting time to finish at the moment if i change tab in browser and after some time came back to application then spinner not dismissing i tried multiple ways but its not working.

public async dismissLoader() {
this.checkAndCloseLoader();
setTimeout(() => this.checkAndCloseLoader(), 1000);
}
public async checkAndCloseLoader() {
const loader = await this.loadingController.getTop();
if (loader !== undefined) {
await this.loadingController.dismiss();
}
}
public async dissmissSpinnerLoader() {
if (this.spinner) await this.spinner.dismiss();
}

setInterval not a correct for my requirement that spinner should dissmiss after api response come.

2 posts - 2 participants

Read full topic

Preview PDF from file data

$
0
0

Hello,

I’m trying to display a file preview with a PDF returned in binary or base64 by an API.
(Why? Because PDFs are generated temporarily and not stored on the server).

I tried @capacitor-community/file-opener but this package requires a filePath and is not compatible for base64 string.

I also tried opening the PDF in the in-app browser or in an HTML element such as or but that doesn’t work either.

I also tried to save the file locally and than get the path to the local file but the method writeFile of the package @capacitor/filesystem seems to only accept url as value in native devices.

Could you tell me if this is possible and if it is, how I can achieve this?

Thanks,
Loïc

1 post - 1 participant

Read full topic

I need to create transparent screen in ionic and continue scanning or upload the picture

$
0
0

Using angular in ionic i need to create transparent screen like camera screen that will continue scanning after scanning we are showing scan text on modal

1 post - 1 participant

Read full topic

White screen after resume application

$
0
0

I am facing a issue that when i resume ionic tabs app after some time, it shows a white screen, on tap it the resume to show the current screen.

Ionic Info

Ionic:

Ionic CLI : 7.2.0 (/Users/sreeraj/.nvm/versions/node/v18.19.0/lib/node_modules/@ionic/cli)
Ionic Framework : @ionic/angular 8.0.0
@angular-devkit/build-angular : 17.3.5
@angular-devkit/schematics : 17.3.5
@angular/cli : 17.3.5
@ionic/angular-toolkit : 11.0.1

Capacitor:

Capacitor CLI : 6.0.0
@capacitor/android : 6.0.0
@capacitor/core : 6.0.0
@capacitor/ios : 6.0.0

Utility:

cordova-res : not installed globally
native-run : 2.0.1

System:

NodeJS : v18.19.0 (/Users/sreeraj/.nvm/versions/node/v18.19.0/bin/node)
npm : 10.2.3
OS : macOS Unknown

1 post - 1 participant

Read full topic

Ion-tabs: How not to cache child routes when switching between tabs

$
0
0

ANSWER THAT RESOLVES THIS:
there is currently no way to do this. But according to Android/IOS guidelines, apps should not behave this way. So maybe it’s for the better. Maybe try to rethink how you are doing things, is it logical? This helped me.

OLD QUESTION:

How not to cache child routes when switching between tabs?

Currently I do:

start: tab1
click on detail button
→ tab1/detail
click on tab2 icon
→ tab2
click on tab1 icon
ACTUAL: → tab1/detail (here the /detail route got cached…)
EXPECTED: → tab1 (I want to make it not cache child routes after switching away from the current tab)

How does one achieve this?

Related questions:

1 post - 1 participant

Read full topic

Viewing all 49234 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>