SendBirdException code=800220, message=Failed to find configured root that contains

I’m having trouble opening a video file that was uploaded from the same device.

  1. Open group chat
  2. Send a video. Wait until it’s sent.
  3. Try to open it.

Expected

  • A pop up asking the user for a suitable app to open the video is displayed

Actual

  • A Toast saying ‘Couldn’t open File’ is displayed.

This use to work in the past, so I’m wondering what has changed.
Also, the video can be played in other conversation participants devices, just not from the sender’s device.

About the app

  • compileSdk 31
  • targetSdk 30
  • Pixel 2. Android 11.
  • SendBird Chat Sdk 3.0.168
  • SendBird UiKit Sdk 2.1.6

Logs

adb logcat | grep SB from the flow described above

08-10 13:12:24.053 10618 10618 I SBUIKIT : [13:12:24.053 ChannelViewModel:onResume():360] ++ channel.getMyMemberState() : JOINED
08-10 13:12:24.054 10618 10618 D SBUIKIT : [13:12:24.053 ChannelViewModel:requestChangeLogs():458] ++ change logs channel url = sendbird_group_channel_105003751_07bd9e3ff44859b95e50930666e1f9f2ce0713b0, lastSyncTs = 1628593920306, hasNext=false
08-10 13:12:24.199 10618 16293 D SBUIKIT : [13:12:24.198 FileInfo$1:call():185] ==============================================================================
08-10 13:12:24.199 10618 16293 D SBUIKIT : [13:12:24.199 FileInfo$1:call():186] ++ FILE PATH : /data/user/0/com.example.android.myapp/cache/Temp_2145265977.mp4
08-10 13:12:24.199 10618 16293 D SBUIKIT : [13:12:24.199 FileInfo$1:call():187] ++ SIZE : 2109765
08-10 13:12:24.200 10618 16293 D SBUIKIT : [13:12:24.199 FileInfo$1:call():188] ++ MIMETYPE : video/mp4
08-10 13:12:24.200 10618 16293 D SBUIKIT : [13:12:24.200 FileInfo$1:call():189] ++ NAME : VID-20210712-WA0006.mp4
08-10 13:12:24.200 10618 16293 D SBUIKIT : [13:12:24.200 FileInfo$1:call():190] ++ THUMBNAIL PATH : /data/user/0/com.example.android.myapp/cache/Temp_2145265977.mp4
08-10 13:12:24.200 10618 16293 D SBUIKIT : [13:12:24.200 FileInfo$1:call():191] ++ THUMBNAIL HEIGHT : 330
08-10 13:12:24.201 10618 16293 D SBUIKIT : [13:12:24.201 FileInfo$1:call():192] ++ THUMBNAIL HEIGHT : 600
08-10 13:12:24.201 10618 16293 D SBUIKIT : [13:12:24.201 FileInfo$1:call():193] ==============================================================================
08-10 13:12:24.204 10618 10618 I SBUIKIT : [13:12:24.204 ChannelViewModel:sendFileMessage():528] ++ request send file message : FileMessageParams{mFileUrlOrFile=/data/user/0/com.example.android.myapp/cache/Temp_2145265977.mp4, mFileName='VID-20210712-WA0006.mp4', mMimeType='video/mp4', mFileSize=2109765, mThumbnailSizes=[ThumbnailSize{mMaxWidth=330, mMaxHeight=600}, ThumbnailSize{mMaxWidth=165, mMaxHeight=300}], mData='null', mCustomType='null', mMentionType=USERS, mMentionedUserIds=null, mPushNotificationDeliveryOption=null, mMetaArrays=null, parentMessageId=0, appleCriticalAlertOptions=null}
08-10 13:12:24.209 10618 10618 D SBUIKIT : [13:12:24.209 ChannelFragment:lambda$initMessageList$15$ChannelFragment():498] ++ result messageList size : 9
08-10 13:12:24.212 10618 10618 D SBUIKIT : [13:12:24.212 ChannelFragment:lambda$initMessageList$13$ChannelFragment():478] ++ a new message requested : BaseMessage{mReqId='1628592715945', mMessage='', mMessageId=0, isSentFromThread='false', parentMessageId='0', mChannelUrl='sendbird_group_channel_105003751_07bd9e3ff44859b95e50930666e1f9f2ce0713b0', channelType='GROUP', mData='', mCustomType='', mCreatedAt=1628593944205, mUpdatedAt=0, mMentionType=USERS, mMentionedUserIds=[], mMentionedUsers=[], mMetaArrays=[], mIsGlobalBlocked=false, mErrorCode=0, mIsSilent=false, forceUpdateLastMessage=false, reactionList=[], sendingStatus=PENDING, messageSurvivalSeconds=-1, parentMessageText=null, threadInfo=ThreadInfo{mostRepliedUsers=[], lastRepliedAt=0, replyCount=0, updatedAt=0}, mSender=User{mUserId='2b79b253-297d-487d-97a9-bd736d0aa30a', mNickname='Mr. Rober Estivi', mProfileUrl='', mFriendDiscoveryKey='null', mFriendName='null', mMetaData={}, mConnectionStatus=NON_AVAILABLE, mLastSeenAt=0, mIsActive=true, mPreferredLanguages=[]}
08-10 13:12:24.212 10618 10618 D SBUIKIT : Sender{mIsBlockedByMe=falserole=NONE}, ogMetaData=null, isOpMsg=false}
08-10 13:12:24.212 10618 10618 D SBUIKIT : FileMessage{, mUrl='', mName='VID-20210712-WA0006.mp4', mSize=2109765, mType='video/mp4', mThumbnails=[Thumbnail{mMaxWidth=330, mMaxHeight=600, mRealWidth=-1, mRealHeight=-1, mUrl='', mRequireAuth=false}, Thumbnail{mMaxWidth=165, mMaxHeight=300, mRealWidth=-1, mRealHeight=-1, mUrl='', mRequireAuth=false}], mRequireAuth=false}, hasNext=false
08-10 13:12:24.219 10618 10618 D SBUIKIT : [13:12:24.218 ViewUtils:drawThumbnail():222] -- will load thumbnail url : /data/user/0/com.example.android.myapp/cache/Temp_2145265977.mp4
08-10 13:12:24.809 10618 10618 D SBUIKIT : [13:12:24.808 ChannelViewModel:requestChangeLogs():458] ++ change logs channel url = sendbird_group_channel_105003751_07bd9e3ff44859b95e50930666e1f9f2ce0713b0, lastSyncTs = 1628593920306, hasNext=false
08-10 13:12:24.989 10618 16314 I SBUIKIT : [13:12:24.989 ChannelViewModel$3:onResult():470] ++ channel message change logs result >> deleted message size : 0, current message size : 7, added message size : 0
08-10 13:12:24.990 10618 16314 I SBUIKIT : [13:12:24.989 ChannelViewModel$3:onResult():477] ++ updated Message size : 0
08-10 13:12:24.990 10618 16314 I SBUIKIT : [13:12:24.990 ChannelViewModel$3:onResult():482] ++ merged message size : 7
08-10 13:12:25.451 10618 16321 I SBUIKIT : [13:12:25.451 ChannelViewModel$3:onResult():470] ++ channel message change logs result >> deleted message size : 0, current message size : 7, added message size : 0
08-10 13:12:25.452 10618 16321 I SBUIKIT : [13:12:25.451 ChannelViewModel$3:onResult():477] ++ updated Message size : 0
08-10 13:12:25.452 10618 16321 I SBUIKIT : [13:12:25.452 ChannelViewModel$3:onResult():482] ++ merged message size : 7
08-10 13:12:26.720 10618 10618 I SBUIKIT : [13:12:26.720 ChannelViewModel$2:onChannelChanged():269] >> ChannelFragnemt::onChannelChanged()
08-10 13:12:26.734 10618 10618 I SBUIKIT : [13:12:26.733 ChannelViewModel:lambda$sendFileMessage$3$ChannelViewModel():543] ++ sent message : BaseMessage{mReqId='1628592715945', mMessage='VID-20210712-WA0006.mp4', mMessageId=1170067526, isSentFromThread='false', parentMessageId='0', mChannelUrl='sendbird_group_channel_105003751_07bd9e3ff44859b95e50930666e1f9f2ce0713b0', channelType='GROUP', mData='', mCustomType='', mCreatedAt=1628593947650, mUpdatedAt=0, mMentionType=USERS, mMentionedUserIds=[], mMentionedUsers=[], mMetaArrays=[], mIsGlobalBlocked=false, mErrorCode=0, mIsSilent=false, forceUpdateLastMessage=false, reactionList=[], sendingStatus=SUCCEEDED, messageSurvivalSeconds=-1, parentMessageText=null, threadInfo=ThreadInfo{mostRepliedUsers=[], lastRepliedAt=0, replyCount=0, updatedAt=0}, mSender=User{mUserId='2b79b253-297d-487d-97a9-bd736d0aa30a', mNickname='Video test', mProfileUrl='', mFriendDiscoveryKey='null', mFriendName='null', mMetaData={}, mConnectionStatus=NON_AVAILABLE, mLastSeenAt=0, mIsActive=true, mPreferredLanguages=null}
08-10 13:12:26.734 10618 10618 I SBUIKIT : Sender{mIsBlockedByMe=falserole=NONE}, ogMetaData=null, isOpMsg=false}
08-10 13:12:26.734 10618 10618 I SBUIKIT : FileMessage{, mUrl='https://file-eu-1.sendbird.com/26cdd5a3579049bfb9d6ecbc9342cd87.mp4', mName='VID-20210712-WA0006.mp4', mSize=2109765, mType='video/mp4', mThumbnails=[], mRequireAuth=true}
08-10 13:12:26.734 10618 10618 D SBUIKIT : [13:12:26.734 FileInfo:clear():238] >> FileInfo::clear()
08-10 13:12:26.739 10618 10618 D SBUIKIT : [13:12:26.738 FileInfo:clear():243] -- file delete=true, path=/data/user/0/com.example.android.myapp/cache/Temp_2145265977.mp4
08-10 13:12:26.745 10618 10618 D SBUIKIT : [13:12:26.744 ChannelFragment:lambda$initMessageList$15$ChannelFragment():498] ++ result messageList size : 9
08-10 13:12:26.750 10618 10618 D SBUIKIT : [13:12:26.749 ChannelFragment:lambda$initMessageList$13$ChannelFragment():478] ++ a new message requested : BaseMessage{mReqId='1628592715945', mMessage='VID-20210712-WA0006.mp4', mMessageId=1170067526, isSentFromThread='false', parentMessageId='0', mChannelUrl='sendbird_group_channel_105003751_07bd9e3ff44859b95e50930666e1f9f2ce0713b0', channelType='GROUP', mData='', mCustomType='', mCreatedAt=1628593947650, mUpdatedAt=0, mMentionType=USERS, mMentionedUserIds=[], mMentionedUsers=[], mMetaArrays=[], mIsGlobalBlocked=false, mErrorCode=0, mIsSilent=false, forceUpdateLastMessage=false, reactionList=[], sendingStatus=SUCCEEDED, messageSurvivalSeconds=-1, parentMessageText=null, threadInfo=ThreadInfo{mostRepliedUsers=[], lastRepliedAt=0, replyCount=0, updatedAt=0}, mSender=User{mUserId='2b79b253-297d-487d-97a9-bd736d0aa30a', mNickname='Mr. Rober Estivi', mProfileUrl='', mFriendDiscoveryKey='null', mFriendName='null', mMetaData={}, mConnectionStatus=NON_AVAILABLE, mLastSeenAt=0, mIsActive=true, mPreferredLanguages=null}
08-10 13:12:26.750 10618 10618 D SBUIKIT : Sender{mIsBlockedByMe=falserole=NONE}, ogMetaData=null, isOpMsg=false}
08-10 13:12:26.750 10618 10618 D SBUIKIT : FileMessage{, mUrl='https://file-eu-1.sendbird.com/26cdd5a3579049bfb9d6ecbc9342cd87.mp4', mName='VID-20210712-WA0006.mp4', mSize=2109765, mType='video/mp4', mThumbnails=[], mRequireAuth=true}, hasNext=false
08-10 13:12:26.765 10618 10618 D SBUIKIT : [13:12:26.765 ViewUtils:drawThumbnail():222] -- will load thumbnail url : /data/user/0/com.example.android.myapp/cache/Temp_2145265977.mp4
08-10 13:12:26.789 10618 10618 D SBUIKIT : [13:12:26.788 ViewUtils:drawThumbnail():222] -- will load thumbnail url : /data/user/0/com.example.android.myapp/cache/Temp_2145265977.mp4
08-10 13:12:26.912 10618 10618 I SBUIKIT : [13:12:26.912 ChannelViewModel$2:onReadReceiptUpdated():238] >> ChannelFragnemt::onReadReceiptUpdated()
08-10 13:12:26.923 10618 10618 D SBUIKIT : [13:12:26.922 ChannelFragment:lambda$initMessageList$15$ChannelFragment():498] ++ result messageList size : 9
08-10 13:12:26.959 10618 10618 D SBUIKIT : [13:12:26.959 ViewUtils:drawThumbnail():222] -- will load thumbnail url : /data/user/0/com.example.android.myapp/cache/Temp_2145265977.mp4
08-10 13:12:28.960 10618 10618 D SBUIKIT : [13:12:28.960 ChannelFragment:onItemClick():981] ++ ChannelFragment::onItemClicked()
08-10 13:12:28.961 10618 10618 D SBUIKIT : [13:12:28.961 FileDownloader:downloadFile():103] ++ request download file url=https://file-eu-1.sendbird.com/26cdd5a3579049bfb9d6ecbc9342cd87.mp4?auth=LONG_TOKEN
08-10 13:12:28.961 10618 10618 D SBUIKIT : [13:12:28.961 FileDownloader:downloadFile():104] ++ isDownloading=false
08-10 13:12:30.403 10618 10618 D SBUIKIT : [13:12:30.402 FileDownloader$1:onResultForUiThread():122] ++ file download Complete file path : /data/user/0/com.example.android.myapp/cache/Downloaded_file_SOME_NAME_SUFFIX.mp4
08-10 13:12:30.406 10618 10618 E SBUIKIT : [13:12:30.406 ChannelFragment$6:onResultForUiThread():968] SendBirdException{code=800220, message=Failed to find configured root that contains /data/data/com.example.android.myapp/cache/Downloaded_file_SOME_NAME_SUFFIX.mp4}
08-10 13:12:30.406 10618 10618 E SBUIKIT : 	at com.sendbird.uikit.tasks.JobResultTask$1.call(JobResultTask.java:26)
08-10 13:12:30.406 10618 10618 E SBUIKIT : 	at com.sendbird.uikit.tasks.JobTask.lambda$getCallable$0$JobTask(JobTask.java:13)
08-10 13:12:30.406 10618 10618 E SBUIKIT : 	at com.sendbird.uikit.tasks.JobTask$$ExternalSyntheticLambda0.call(Unknown Source:2)
08-10 13:12:30.406 10618 10618 E SBUIKIT : 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
08-10 13:12:30.406 10618 10618 E SBUIKIT : 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
08-10 13:12:30.406 10618 10618 E SBUIKIT : 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
08-10 13:12:30.406 10618 10618 E SBUIKIT : 	at java.lang.Thread.run(Thread.java:923)

Hi @robertoestivill,

That is some strange behavior. Let me see if I can recreate this and we’ll go from there.

1 Like

Hi @robertoestivill
I guess your file provider overwrites our UIKit file provider.
How did you implement file provider?!

Hi @Doo_Rim

I guess your file provider overwrites our UIKit file provider.

It does not.
I have subclassed androidx.core.content.FileProvider and configured it with a different provider paths.

Screenshot 2021-08-17 at 11.03.48
Screenshot 2021-08-17 at 11.03.58

I think you don’t define
<root-path name="root" path="."/> in your file_provider_paths.xml.

If app wants to access removable SD card, we should define <root-path name="root" path="."/>.

Hi @Doo_Rim

You are correct in the sense that I do not have <root-path name="root" path="."/> declared in my own file_provider_paths.xml

However, this should not be necessary as the media is being accessed from the SDK using the SDK FileProvider, which does contain <root-path name="root" path="."/> in the sb_file_paths.xml

Also, file provider entries doesn’t seem to override each other, meaning that my config is not overriding SendBird’s. I can see both path configuration files (mine and SendBird) in the final apk.


Screenshot 2021-08-19 at 09.46.14

I will still give your suggestion a try though.

Update:

I added <root-path name="root" path="."/> to my file_provider_paths.xml and seems to be working. I’m quite puzzled about how can this be possible.
Any quick explanation or doc link would be much appreciated.
Probably also worth mentioning in the documentation (unless a whole revamp is on it’s way based on the discussion here: SendBird UiKit using androidx.core.content.FileProvider directly )

1 Like

Hi, @robertoestivill
I found the reason why your overwrite UIKit .

When AndroidManifest.xml files are merged, there is a priority.
Of course, your app Maifest.xml file is higher.

When they are merged, the compiler determines the key.
You can see what the key is for each attribute.

For , the compiler matches the key as android:name.

So, there is no way to use uikit and your app xml files which indicate paths.
Although I try your suggestion ( SendBird UiKit using androidx.core.content.FileProvider directly ) , it cannot resolve this issue.

I think the only way is to define the right paths to your .xml file.

Thanks for the research @Doo_Rim
I find it hard to believe that the override is the problem here, so I did more research.

I don’t see the problem you mention about the manifest merger overriding any resource.
In the following screen you can see how both file providers are perfectly added to the final manifest, each with it’s own provider file paths.

However, what I do see, is that the SendBird SDK is using a basic authority for it’s provider. This accidentally clashes with the authority defined for my FileProvider subclass, as it’s my application package/id + “.provider”, basically the documentation recommendation.

This is the key issue.

If I change my authority to something different, everything works without me adding the root-path to my file provider paths.

This is SendBird miss using the application id (of which you should have no control or use) for configuring internal components.
As I said on the other report, as an SDK provider, you should have your own FileProvider subclass and authority to not interfere with the application in which your SDK is running.

The other report should still be a valid and all this should be documented somewhere.

Thank you! Let me check it!

Hi, @robertoestivill

I am sorry I couldn’t understand what the problem is.
What I understood is

  1. android:authorities attribute specifies the URI authority that you want to use for content URIs generated by the FileProvider . When customers provide files, file will be provided from their application. So, SendBird UIKit follow application id as a authorities.

  2. Customers cannot use multiple <meta-data> due to the same android:name. There is no way to use UIKit xml paths, if they define their own paths.

  3. If customers want to use their own xml paths, they should define their own FileProvider or android:replace.

SendBird UIKit has a responsibility to inform using FileProvider. Because it is essential to share files due to the nature of chat, the use of a file provider is inevitable, and I think that customers need to know and use it to their own FileProvider paths.

@Doo_Rim
The problem ended up being that the two different FileProviders were using the same authority.
This caused the FileProvider.getUriForFile() to miss behave.

This was happening, because the SendBird sdk was using my application id as it’s authority.
From my point of view, only components declared by the application developer should be using the application id.

This again, is why I have raised the topic of SendBird using a subclass of FileProvider and a SendBird specific authority that the sdk can use internally, as oppose of taking the default FileProvider class name and application id authority, that most likely will be use by the application developer and cause clashes.

Application developers should not have to work around constraints added by external sdks.

@robertoestivill
Thank you for your suggestion! I understood your concern.
We will discuss it internally. Thank you!

1 Like