Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: "Preferences" plugin is not implemented on android #127

Closed
4 tasks done
FreePhoenix888 opened this issue Sep 21, 2023 · 3 comments
Closed
4 tasks done

Error: "Preferences" plugin is not implemented on android #127

FreePhoenix888 opened this issue Sep 21, 2023 · 3 comments
Labels
bug Something isn't working help wanted Extra attention is needed sweep

Comments

@FreePhoenix888
Copy link
Member

FreePhoenix888 commented Sep 21, 2023

Description

I get Error: "Preferences" plugin is not implemented on android error in android app.

How to reproduce

  • Run these commands:
git clone https://github.com/deep-foundation/deep-memo-app.git &&
cd deep-memo-app &&
npm install &&
npm run build-android &&
npx cap open android
  • Run android app in android studio (note that android studio will be opened by npx cap open android command)
  • Open logcat and write package:mine in filter
  • You will see these logs:
2023-09-21 12:11:52.289  9452-9452  Capacitor/Console       com.deepfoundation.deep              E  File: http://localhost/_next/static/chunks/6528-b514891395204322.js - Line 1 - Msg: Uncaught (in
                                                                                                    promise) Error: "Preferences" plugin is not implemented on android

Additional Information

Version of @capacitor/preferences

freephoenix888@FreePhoenix888:~/Programming/deep/deep-memo-app$ npm list @capacitor/preferences
@deep-foundation/[email protected] /home/freephoenix888/Programming/deep/deep-memo-app
├── @capacitor/[email protected]
├─┬ @deep-foundation/[email protected]
│ └─┬ @deep-foundation/[email protected]
│   └── @capacitor/[email protected] deduped
└─┬ @deep-foundation/[email protected]
  └── @capacitor/[email protected] deduped

Direct capacitor dependencies

freephoenix888@FreePhoenix888:~/Programming/deep/deep-memo-app$ npm list | grep capacitor
├── @capacitor-community/[email protected]
├── @capacitor-community/[email protected]
├── @capacitor/[email protected]
├── @capacitor/[email protected]
├── @capacitor/[email protected]
├── @capacitor/[email protected]
├── @capacitor/[email protected]
├── @capacitor/[email protected]
├── @capacitor/[email protected]
├── @capacitor/[email protected]
├── @deep-foundation/[email protected]
├── @deep-foundation/[email protected]
├── @deep-foundation/[email protected]
├── @deep-foundation/[email protected]
├── @deep-foundation/[email protected]
├── @deep-foundation/[email protected]
├── [email protected]

Capacitor dependencies (depth 10)

freephoenix888@FreePhoenix888:~/Programming/deep/deep-memo-app$ npm list --depth 10 | grep capacitor
├─┬ @capacitor-community/[email protected]
│ └── @capacitor/[email protected] deduped
├─┬ @capacitor-community/[email protected]
│ ├─┬ @capacitor/[email protected]
│ ├─┬ @capacitor/[email protected]
├─┬ @capacitor/[email protected]
│ └── @capacitor/[email protected] deduped
├─┬ @capacitor/[email protected]
├─┬ @capacitor/[email protected]
├─┬ @capacitor/[email protected]
│ └── @capacitor/[email protected] deduped
├─┬ @capacitor/[email protected]
│ └── @capacitor/[email protected] deduped
├─┬ @capacitor/[email protected]
│ └── @capacitor/[email protected] deduped
├─┬ @capacitor/[email protected]
│ └── @capacitor/[email protected] deduped
├─┬ @capacitor/[email protected]
│ └── @capacitor/[email protected] deduped
├─┬ @deep-foundation/[email protected]
│ ├─┬ @capacitor/[email protected]
│ │ └── @capacitor/[email protected] deduped
│ ├─┬ @deep-foundation/[email protected]
│ │ ├── @capacitor/[email protected] deduped
├─┬ @deep-foundation/[email protected]
│ ├── @capacitor/[email protected] deduped
├─┬ @deep-foundation/[email protected]
│ ├─┬ @capacitor/[email protected]
│ │ └── @capacitor/[email protected] deduped
├─┬ @deep-foundation/[email protected]
│ ├── @capacitor/[email protected] deduped
│ ├─┬ @capacitor/[email protected]
│ │ └── @capacitor/[email protected] deduped
│ ├─┬ @deep-foundation/[email protected]
│ │ ├── @capacitor/[email protected] deduped
├─┬ @deep-foundation/[email protected]
│ ├─┬ @capacitor/[email protected]
│ │ └── @capacitor/[email protected] deduped
│ ├─┬ @deep-foundation/[email protected]
│ │ ├── @capacitor/[email protected] deduped
├─┬ @deep-foundation/[email protected]
│ ├── [email protected] deduped
│ │ ├── @capacitor/[email protected] deduped
│ │ ├── @capacitor/[email protected] deduped
│ │ │ │ ├─┬ @types/[email protected]
│ │ │ │ ├── [email protected]
│ ├── @capacitor/[email protected] deduped
│ ├─┬ @capacitor/[email protected]
│ │ └── @capacitor/[email protected] deduped
│ ├─┬ @deep-foundation/[email protected]
│ │ ├── @capacitor/[email protected] deduped
│ ├── @capacitor/[email protected] deduped
│ ├── @capacitor/[email protected] deduped
├─┬ [email protected]
│ ├── @capacitor/[email protected] deduped
Checklist
  • package.json ❌ Failed
• Check if "@capacitor/preferences" is listed in the "dependencies" section. If not, add it with the correct version.
  • android/capacitor.settings.gradle ✅ Commit e8da91d
• Check if the Preferences plugin is included in the file. If not, add the following lines: include ':@capacitor/preferences' project(':@capacitor/preferences').projectDir = new File('../node_modules/@capacitor/preferences/android')
  • components/page.tsx ✅ Commit 1a936da
• Check if the Preferences plugin is correctly imported at the top of the file. If not, add the following line: import { Preferences } from '@capacitor/preferences'; • Check if the Preferences plugin is correctly used in the code. If not, correct the usage according to the plugin documentation.
  • android/app/src/main/java/com/deepfoundation/deep/MainActivity.java ✅ Commit 8c9ace4
• Check if the Preferences plugin is correctly initialized for Android. If not, add the following lines in the onCreate method: import com.capacitor.preferences.Preferences; ... this.init(savedInstanceState, new ArrayList>() {{ ... add(Preferences.class); ... }});
@FreePhoenix888 FreePhoenix888 added bug Something isn't working help wanted Extra attention is needed labels Sep 21, 2023
@Konard
Copy link
Member

Konard commented Sep 21, 2023

sweep fix it

@FreePhoenix888
Copy link
Member Author

Sweep: fix it

@deep-foundation-sweepai
Copy link

deep-foundation-sweepai bot commented Sep 22, 2023

Here's the PR! #128.

💎 Sweep Pro: I'm creating this ticket using GPT-4. You have unlimited GPT-4 tickets.

Actions (click)

  • ↻ Restart Sweep

Step 1: 🔎 Searching

I found the following snippets in your repository. I will now analyze these snippets and come up with a plan.

Some code snippets I looked at (click to expand). If some file is missing from here, you can mention the path in the ticket description.

import { Box, Button, Card, CardBody, CardHeader, Heading, Link, Stack, Text, VStack, useToast } from "@chakra-ui/react";
import { DeepClient } from "@deep-foundation/deeplinks/imports/client";
import { JsonToTable } from "react-json-to-table";
import { JSONToHTMLTable } from '@kevincobain2000/json-to-html-table'
import { ErrorAlert } from "./error-alert";
import { toggleLogger } from "./toggle-logger";
import { makeLoggerToggleHandler } from "../imports/make-logger-toggle-handler";
import { useState } from "react";
import NextLink from "next/link";
import {LinkIcon} from '@chakra-ui/icons'
import debug from "debug";
import { QueryLink } from "@deep-foundation/deeplinks/imports/client_types";
import { JsonView, allExpanded, darkStyles, defaultStyles } from 'react-json-view-lite';
import 'react-json-view-lite/dist/index.css';
import { OptionalPackages } from "../imports/optional-packages";
export function Monitoring(options: MonitoringOptions) {
const log = debug(`deep-memo-app:${Monitoring.name}`)
log({options})
const { deep, isLoggerEnabled,deviceLinkId} = options;
const useDeepSubscriptionQuery: QueryLink = {
up: {
tree_id: deep.idLocal(OptionalPackages.Logger, "LogTree"),
parent: {
type_id: {
_id: ["@deep-foundation/logger", "LogUpdate"]
},
out: {
type_id: {
_id: ["@deep-foundation/logger", "LogId"]
},
to: {
_or: [
{
type_id: {
_id: ["@deep-foundation/capacitor-motion", "Motion"]
},
},
{
type_id: {
_id: ["@deep-foundation/capacitor-device", "Device"]
},
},
{
type_id: {
_id: ["@deep-foundation/capacitor-geolocation", "Position"]
},
}
],
in: {
type_id: {
_id: ["@deep-foundation/core", "Contain"]
},
from_id: {
_in: [deep.linkId, deviceLinkId]
}
}
}
}
}
}
}
log({useDeepSubscriptionQuery})
const { data: linksDownToLogUpdate } = deep.useDeepSubscription(useDeepSubscriptionQuery)
log({logObjectLinks: linksDownToLogUpdate})
return (
<Stack>
{
isLoggerEnabled ? (
linksDownToLogUpdate.length === 0 ? (
<Text>
No logs
</Text>
) : (
linksDownToLogUpdate.filter(link => link.type_id === deep.idLocal(OptionalPackages.Logger, "LogUpdate")).map(logUpdateLink => {
const logIdLink = linksDownToLogUpdate.find(link => link.type_id === deep.idLocal(OptionalPackages.Logger, "LogId") && link.from_id === logUpdateLink.id)
const linkBeingLogged = linksDownToLogUpdate.find(link => link.id === logIdLink.to_id)
const nameOfTypeOfLinkBeingLogged = deep.nameLocal(linkBeingLogged.type_id)
const logObjectLink = linksDownToLogUpdate.find(link => link.type_id === deep.idLocal(OptionalPackages.Logger, "LogObject") && link.from_id === logUpdateLink.id)
const logTimestamp = linksDownToLogUpdate.find(link => link.type_id === deep.idLocal(OptionalPackages.Logger, "LogTimestamp") && link.from_id === logUpdateLink.id)
const humanReadableTimestamp = new Date(logTimestamp.value.value).toLocaleString()
return (
<Card>
<CardHeader>
<Heading>
{nameOfTypeOfLinkBeingLogged}
</Heading>
</CardHeader>
<CardBody>
<Text>

https://github.com/deep-foundation/deep-memo-app/blob/a311199df3b87efade46383dc68a4e80ca9607b6/imports/contact/package-name.ts#L1-L0

import { DEEP_MEMO_PACKAGE_NAME } from '../imports/package-name';
import { WithProvidersAndLogin } from './with-providers-and-login';
import { StoreProvider } from './store-provider';
import { Alert, AlertDescription, AlertIcon, AlertTitle, Button, CircularProgress, Heading, List, ListIcon, ListItem, Stack, Text, Toast, VStack, useToast } from '@chakra-ui/react';
import { useCapacitorStore } from '@deep-foundation/store/capacitor';
import { CapacitorStoreKeys } from '../imports/capacitor-store-keys';
import { WithDeviceSync } from '@deep-foundation/capacitor-device';
import {
DeepClient,
DeepProvider,
SerialOperation,
useDeep,
} from '@deep-foundation/deeplinks/imports/client';
import { WithMinilinksApplied } from './with-minilinks-applied';
import { createSerialOperation } from '@deep-foundation/deeplinks/imports/gql';
import error from 'next/error';
import { ErrorAlert } from './error-alert';
import { RequiredPackages } from '../imports/required-packages';
import { useEffect, useState } from 'react';
import { NpmPackagerProxy } from '../imports/npm-packager-proxy';
import debug from 'debug';
import { WithDecoratedDeep } from './with-decorated-deep';
import { Contacts } from '@capacitor-community/contacts';
import { Device } from '@capacitor/device';
import { Motion } from '@capacitor/motion';
import { Geolocation } from '@capacitor/geolocation';
import { Camera } from '@capacitor/camera';
import { Network } from '@capacitor/network';
import { DecoratedDeep } from '../imports/decorated-deep';
export interface PageParam {
renderChildren: (param: {
deep: DecoratedDeep;
deviceLinkId: number;
}) => JSX.Element;
}
export function Page({ renderChildren }: PageParam) {
const log = debug(`deep-memo-app:${Page.name}`)
const toast = useToast();
const [isInstallationLoading, setIsInstallationLoading] = useState<boolean|undefined>(undefined);
log({isInstallationLoading, setIsInstallationLoading})
useEffect(() => {
self['CapacitorDevice'] = Device
self['CapacitorMotion'] = Motion
self['CapacitorGeolocation'] = Geolocation
self['CapacitorCamera'] = Camera
self['CapacitorNetwork'] = Network
self['CapacitorContact'] = Contacts
})
return (
<StoreProvider>
<WithProvidersAndLogin>
<WithDeep
renderChildren={({ deep }) => (
<WithDecoratedDeep deep={deep} renderChildren={({deep}) => (
<WithPackagesInstalled
deep={deep}
packageNames={[DEEP_MEMO_PACKAGE_NAME, ...Object.values(RequiredPackages)]}
renderIfError={(error) => <VStack height="100vh" justifyContent={"center"}><ErrorAlert title={"Failed to check whether required packages are installed"} description={error.message} /></VStack>}
renderIfNotInstalled={(notInstalledPackageNames) => {
log({notInstalledPackageNames})
const isDeepMemoInstalled = !notInstalledPackageNames.includes(DEEP_MEMO_PACKAGE_NAME);
log({isDeepMemoInstalled})
return (
<VStack height="100vh" justifyContent={"center"}>
{
isDeepMemoInstalled ? (
<ErrorAlert title={`${DEEP_MEMO_PACKAGE_NAME} is installed but its dependencies-packages are not installed`} description={
<VStack>
<List styleType="disc">
{
notInstalledPackageNames.map((packageName) => (
<ListItem >
{packageName}
</ListItem>
))
}
</List>
</VStack>
} />
) : (
<VStack>
<ErrorAlert title={`${DEEP_MEMO_PACKAGE_NAME} is not installed`} />
{/* <Button
isLoading={isInstallationLoading}
onClick={async () => {
setIsInstallationLoading(true)
try {
const npmPackagerProxy = new NpmPackagerProxy(deep);
await npmPackagerProxy.applyMinilinks()
await npmPackagerProxy.install(DEEP_MEMO_PACKAGE_NAME)
} catch (error) {
toast({
title: `Failed to install ${DEEP_MEMO_PACKAGE_NAME}`,
description: error.message,
status: "error",
duration: null,
isClosable: true,
})
} finally {
setIsInstallationLoading(false)
}
}}
>
Install {DEEP_MEMO_PACKAGE_NAME}
</Button> */}
</VStack>
)
}
</VStack>
);
}}
renderIfLoading={() => (
<VStack height="100vh" justifyContent={"center"}>
<CircularProgress isIndeterminate />
<Text>Checking if deep packages are installed...</Text>
</VStack>
)}
>
<WithMinilinksApplied deep={deep}>
<WithDeviceLinkId
deep={deep}
renderChildren={({ deviceLinkId }) =>
renderChildren({ deep, deviceLinkId })
}
/>
</WithMinilinksApplied>
</WithPackagesInstalled>
)} />
)}
/>
</WithProvidersAndLogin>

// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
include ':capacitor-android'
project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor')
include ':capacitor-community-contacts'
project(':capacitor-community-contacts').projectDir = new File('../node_modules/@capacitor-community/contacts/android')
include ':capacitor-device'
project(':capacitor-device').projectDir = new File('../node_modules/@capacitor/device/android')
include ':capacitor-dialog'
project(':capacitor-dialog').projectDir = new File('../node_modules/@capacitor/dialog/android')
include ':capacitor-haptics'
project(':capacitor-haptics').projectDir = new File('../node_modules/@capacitor/haptics/android')
include ':capacitor-voice-recorder'

DeepClient,
} from '@deep-foundation/deeplinks/imports/client';
import NextLink from 'next/link';
import {LinkIcon} from '@chakra-ui/icons'
import { WithSubscriptions } from '../components/with-subscriptions';
import { NavBar } from '../components/navbar';
import { Page } from '../components/page';
import { CapacitorStoreKeys } from '../imports/capacitor-store-keys';
import { useCapacitorStore } from '@deep-foundation/store/capacitor';
import { Monitoring } from '../components/monitoring';
import { SETTINGS_ROUTES } from '../imports/settings-routes';
import { capitalCase } from 'case-anything';
import debug from 'debug';
import { ErrorAlert } from '../components/error-alert';
import { WithPackagesInstalled } from '@deep-foundation/react-with-packages-installed';
import { OptionalPackages } from '../imports/optional-packages';
import { DecoratedDeep } from '../imports/decorated-deep';
import { updateDevice } from '@deep-foundation/capacitor-device';
interface ContentParam {
deep: DecoratedDeep;
deviceLinkId: number;
}
function Content({ deep, deviceLinkId }: ContentParam) {
useEffect(() => {
import('@ionic/pwa-elements/loader').then(({ defineCustomElements }) => {
defineCustomElements(window);
});
}, []);
useEffect(() => {
new Promise(async () => {
if (deep.linkId !== 0) {
return;
}
await deep.guest();
});
}, [deep]);
const [isContactsSyncEnabled, setIsContactsSyncEnabled] = useCapacitorStore<boolean|undefined>(
CapacitorStoreKeys[CapacitorStoreKeys.IsContactsSyncEnabled],
undefined
);
const [lastContactsSyncTime, setLastContactsSyncTime] = useCapacitorStore<number|undefined>(
CapacitorStoreKeys[CapacitorStoreKeys.ContactsLastSyncTime],
undefined
);
const [isCallHistorySyncEnabled, setIsCallHistorySyncEnabled] = useCapacitorStore<boolean|undefined>(
CapacitorStoreKeys[CapacitorStoreKeys.IsCallHistorySyncEnabled],
undefined
);
const [lastCallHistorySyncTime, setLastCallHistorySyncTime] = useCapacitorStore<number | undefined>(
CapacitorStoreKeys[CapacitorStoreKeys.CallHistoryLastSyncTime],
undefined
);
const [isNetworkSyncEnabled, setIsNetworkSyncEnabled] =
useCapacitorStore<boolean|undefined>(
CapacitorStoreKeys[CapacitorStoreKeys.IsNetworkSubscriptionEnabled],
false
);
const [isVoiceRecorderEnabled, setIsVoiceRecorderEnabled] = useCapacitorStore<boolean|undefined>(
CapacitorStoreKeys[CapacitorStoreKeys.IsVoiceRecorderEnabled],
undefined
);
const [isLoggerEnabled, setIsLoggerEnabled] = useCapacitorStore(
CapacitorStoreKeys[CapacitorStoreKeys.IsLoggerEnabled],
undefined
);
const [isMotionSyncEnabled, setIsMotionSyncEnabled] = useCapacitorStore<boolean|undefined>(
CapacitorStoreKeys[CapacitorStoreKeys.IsMotionSyncEnabled],
undefined
);
const [isGeolocationSyncEnabled, setIsGeolocationSyncEnabled] = useCapacitorStore<boolean|undefined>(
CapacitorStoreKeys[CapacitorStoreKeys.IsGeolocationSyncEnabled],
undefined
);
return (
<Stack alignItems={'center'}>
<NavBar />
<Heading as={'h1'}>DeepMemo</Heading>
<Button onClick={async () => {
await deep.updateDevice({
deviceLinkId
})
}}>
Update Device Info
</Button>
<WithSubscriptions
deep={deep}
deviceLinkId={deviceLinkId}
isContactsSyncEnabled={isContactsSyncEnabled}
lastContactsSyncTime={lastContactsSyncTime}
onLastContactsSyncTimeChange={setLastContactsSyncTime}
isCallHistorySyncEnabled={isCallHistorySyncEnabled}
lastCallHistorySyncTime={lastCallHistorySyncTime}
onLastCallHistorySyncTimeChange={setLastCallHistorySyncTime}
isNetworkSyncEnabled={isNetworkSyncEnabled}
isVoiceRecorderEnabled={isVoiceRecorderEnabled}
isMotionSyncEnabled={isMotionSyncEnabled}
isGeolocationSyncEnabled={isGeolocationSyncEnabled}
/>

I also found the following external resources that might be helpful:

Summaries of links found in the content:

https://github.com/deep-foundation/deep-memo-app.git:

The page is a GitHub repository for the project "deep-memo-app" by deep-foundation. The repository contains code for a memo app developed using Capacitor, a cross-platform app development framework. The user is experiencing an error related to the "Preferences" plugin in the Android version of the app. The error message suggests that the plugin is not implemented on Android. The user provides additional information about the versions of the "@capacitor/preferences" plugin and other Capacitor dependencies used in the project. The user also includes steps to reproduce the error and logs from the Android app.


Step 2: ⌨️ Coding

  • package.json ❌ Failed
• Check if "@capacitor/preferences" is listed in the "dependencies" section. If not, add it with the correct version.
  • android/capacitor.settings.gradle ✅ Commit e8da91d
• Check if the Preferences plugin is included in the file. If not, add the following lines: include ':@capacitor/preferences' project(':@capacitor/preferences').projectDir = new File('../node_modules/@capacitor/preferences/android')
  • components/page.tsx ✅ Commit 1a936da
• Check if the Preferences plugin is correctly imported at the top of the file. If not, add the following line: import { Preferences } from '@capacitor/preferences'; • Check if the Preferences plugin is correctly used in the code. If not, correct the usage according to the plugin documentation.
  • android/app/src/main/java/com/deepfoundation/deep/MainActivity.java ✅ Commit 8c9ace4
• Check if the Preferences plugin is correctly initialized for Android. If not, add the following lines in the onCreate method: import com.capacitor.preferences.Preferences; ... this.init(savedInstanceState, new ArrayList>() {{ ... add(Preferences.class); ... }});

Step 3: 🔁 Code Review

I have finished reviewing the code for completeness. I did not find errors for sweep/fix-preferences-plugin-error.

.


🎉 Latest improvements to Sweep:


💡 To recreate the pull request edit the issue title or description. To tweak the pull request, leave a comment on the pull request.
Join Our Discord

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed sweep
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants