Mobile internet identity login not working

The button works, but internet identity login is not triggering properly on mobile. I saw some previous forum posts, but wasn’t able to resolve the issue with them… @kpeacock @icme @infu

Here is my init and login methods in my Svelte store. Thank you for any help in advance!

function createAuthStore() {
	const { subscribe, set, update } = writable({
		isReady: false,
		isAuthenticated: false,
		isApproved: false, //this is so that the minter backend can burn tokens on behalf of user
		identity: null,
		tokenActor: null,
		minterActor: null,
		authClient: null,
		balance: 0,
		info: [],
	});

	return {
		subscribe,
		init: async () => {
			const authClient = await AuthClient.create(defaultOptions.createOptions);
			const isAuthenticated = await authClient.isAuthenticated();
			const identity = isAuthenticated ? authClient.getIdentity() : null;
			const minterActor = minterActorFromIdentity(identity);
			const tokenActor = tokenActorFromIdentity(identity);

			let balance;
			let isApproved;
			let info;

	try {
		if (identity) {			
			const playerInfo = await minterActor.getPlayer();
			// Fetch the balance
			const fetchedBalance = await fetchTokenBalance(tokenActor, identity.getPrincipal());
			balance = fetchedBalance;  // Set the balance to the fetched value
			
			// Check approval again if necessary
			if(playerInfo.err) {
				let result = await getApproval(tokenActor, minterBackendId);
				isApproved = result ? result : false;
				info = playerInfo.err;
			}
			if(playerInfo.ok) {
				isApproved = true;
				info = playerInfo.ok;
			}
		}
	} catch (error) {
		console.error("Error during init:", error);
		// You can set some error state here if needed
	}
			set({
				balance,
				isAuthenticated,
				isApproved,
				identity,
				minterActor,
				tokenActor,
				authClient,
				isReady: true,
			});
		},

		login: async () => {
			const authClient = await AuthClient.create();
			await new Promise((resolve) => {
				authClient.login({
					identityProvider: defaultOptions.loginOptions.identityProvider,
					derivationOrigin:
						process.env.DFX_NETWORK === "ic"
							? `https://${frontendId}.icp0.io`
							: null,
					
					onSuccess: async () => {
						const isAuthenticated = await authClient.isAuthenticated();
						const identity = isAuthenticated ? authClient.getIdentity() : null;
						const minterActor = minterActorFromIdentity(identity);
						const tokenActor = tokenActorFromIdentity(identity);

						let isApproved = false;
						let balance = 0;
						let info = []

						if (identity) {			
							const playerInfo = await minterActor.getPlayer();
							// Fetch the balance
							const fetchedBalance = await fetchTokenBalance(tokenActor, identity.getPrincipal());
							balance = fetchedBalance;  // Set the balance to the fetched value
							
							// Check approval again if necessary
							if(playerInfo.err) {
								let result = await getApproval(tokenActor, minterBackendId);
								isApproved = result ? result : false;
								info = playerInfo.err;
							}
							if(playerInfo.ok) {
								isApproved = true;
								info = playerInfo.ok;
							}
						}
						
						// console.log(Principal.fromText(identity));

						set({
							balance,
							isAuthenticated,
							isApproved,
							identity,
							minterActor,
							tokenActor,
							authClient,
							isReady: true,
							info,
						});

						resolve();
					},
				});
			});
		},
1 Like

Yeah, you’re doing the thing that I think I need to find some way of protecting against.

Safari in particular doesn’t want you to do async tasks in between the click event and invoking window.open. Awaiting AuthClient.create before calling login is causing your problem, because it needs to make an async call to indexeddb

Instead, you should initialize the authclient first and store a reference to it. Then, directly invoke authClient.login() during the click handler.

Here is our example code for svelte: https://github.com/dfinity/examples/motoko/auth_client
-demo

You can see in the example, we only call login if the client has been created already, and we return if isReady hasn’t been updated. Then in the application, we simply call init during the onmount of the page

2 Likes

To help with the documentation, was there a tutorial you were following, or were you just working from the readme of the auth-client package? I’d like to help fewer people encounter this issue in the future

2 Likes

Hey Kai, thank you for the comprehensive response. I was repurposing code that I found from another project, not sure what resources they used to set up their auth, so it’s hard to answer your question.

I think it’s very well laid out in the example repo you sent over, thank you for your help.

Theo

1 Like

Was this moved Kai? Where can i find base login template for svelte?

Looks like the team thought my example was duplicative of the one maintained by the II team. Here’s the example on my personal Github:

1 Like