Open steadev opened 2 months ago
I also have a problem on my app using the very same package version, it crashes in production when attempting to access contacts. I my case it crashes before asking user for permission. The Debug version works fine though. I have not investigated it might be it crashes for the same reasons as yours. iOS works fine also for me.
I see there is a new version 6.1.1 I will test that.
Upgrading to version 6.1.1 did not fix my problem
the problem still exists
I have exactly the same problem. On Android the app does not even try to open permission dialog. Strange thing is that even when I completely remove my app and install it again, it does not even ask for permissions and automatically fails as denied. In the app details on Android I see that the permission is denied. If anyone knows how to fix this it would be highly appreciated.
Can someone from the dev team please let us know if this is going to be fixed? Thanks.
We're using the helpers provided by the Capacitor code itself. We don't do any logic on this. Are you sure you added the necessary lines in AndroidManifest.xml
? Could you please share a reproduction
Yes, I added the permissions to the manifest file, checked everything 20 times. It does not make any sense. Maybe the helpers are not working ok in later versions of Android. I am going to check that too.
Below is the complete service class we are using.
import axios from 'axios'
import responseInterceptor from './response.interceptor'
import authInterceptor from './auth.interceptor'
import {Contacts} from '@capacitor-community/contacts'
import {storage} from './storage'
import {generateAvatarInitials} from '../utils/generateAvatarInitials'
import {store} from '../store'
const API_URL = import.meta.env.VITE_API_URL
class ContactService {
api
constructor() {
this.api = axios.create({baseURL: API_URL})
authInterceptor(this.api)
responseInterceptor(this.api)
}
async fetchContactsFromPhone(term) {
try {
const perms = await Contacts.getPermissions()
if (perms.granted || perms.contacts === 'granted') {
console.debug('ContactService.fetchContactsFromPhone: Permissions granted')
const {contacts} = await Contacts.getContacts()
console.debug('ContactService.fetchContactsFromPhone: fetched contacts:')
console.debug(contacts)
term = term.toLowerCase()
return contacts
.map(this.mapLocalContactToContact)
.filter(c => c.fullname?.length)
.filter(c => {
if (!term?.length) {
return true
}
return c.fullname?.toLowerCase().includes(term) ||
c.phone?.toLowerCase().includes(term) ||
c.phone?.replace(/ /g, '').toLowerCase().includes(term) ||
c.email?.toLowerCase().includes(term)
})
} else {
console.warn('ContactService.fetchContactsFromPhone: Permissions not granted')
console.warn(perms)
}
} catch (e) {
if (e.code === 'UNIMPLEMENTED') {
console.error('Cannot fetch local contacts from the device.')
} else {
console.error(e)
}
}
console.warn('ContactService.fetchContactsFromPhone: Returning empty array')
return []
}
async fetchListCached() {
return await storage.getJSON('contacts') || []
}
async fetchList(filter, term, page, options) {
let url = `contacts?page=${page}&filter=${encodeURIComponent(JSON.stringify(filter))}`
url = options?.limit ? url += `&limit=${options.limit}` : url
url = options?.sort ? url += `&sort=${options.sort}` : url
url = options?.sortDir ? url += `&sortDir=${options.sortDir}` : url
let res
try {
const response = await this.api.get(url)
res = response.data
res.items = res.items
.map(i => {
if (!i.fullname?.trim().length) {
i.fullname = i.phone || i.email
}
return i
})
.filter(i => i.fullname?.length)
} catch (e) {
if (e.response?.status === 401) {
store.commit('logout')
}
console.error(e)
//return []
}
const localContacts = await this.fetchContactsFromPhone(term)
// console.log('local contacts')
// console.log(localContacts)
res.items = [...localContacts, ...res.items]
.map(i => {
i.avatar = generateAvatarInitials(i.fullname || i.email)
i.sort = i.firstname || i.surname || i.fullname || i.phone || i.email
return i
})
.filter(i => i.fullname?.length)
.sort((a, b) => a.sort?.toString().localeCompare(b.sort))
storage.setJSON('contacts', res.items)
return res
}
async fetchItem(id, isLocal) {
let contact
if (isLocal) {
const {contacts} = await Contacts.getContacts()
contact = contacts.find(i => i.contactId === id)
if (contact) {
return this.mapLocalContactToContact(contact)
}
} else {
contact = await this.api.get(`contacts/${id}`).then(response => response.data)
}
contact.avatar = generateAvatarInitials(contact.fullname || contact.email)
return contact
}
mapLocalContactToContact(i) {
const firstPhoneNumber = i.phoneNumbers?.length ? i.phoneNumbers[0].number : null
const firstEmail = i.emails?.length ? i.emails[0].address : null
return {
_id: i.contactId,
local: true,
fullname: i.displayName || firstPhoneNumber || firstEmail || null,
phone: firstPhoneNumber,
email: firstEmail,
company: i.company || null
}
}
async createNewContact(data) {
const {data: res} = await this.api.post('/contacts', data)
return res
}
async updateContact(id, data) {
const {data: res} = await this.api.put(`contacts/${id}`, data)
return res
}
async deleteContact(id) {
return await this.api.delete(`contacts/${id}`)
}
}
export default new ContactService()
Without a reproduction we won't be able to help you unfortunately
version: 6.0.6
Describe the bug A clear and concise description of what the bug is.
checkPermissions
always return 'denied', even though permission granted.requestPermissions
returns 'granted'..and for
checkPermissions
, ios works fine