Unable to recieve value of getquery parameter in Firebase Dynamic Links - firebase

I have to add an extra parameter as "meetingToken" in firebase deeplink .
But On adding an extra parameter "meetingtoken" as queryparameter im not recieving the value and getting error in joinmeeting(it) : No value passed for parameter meetingToken.
While the same works fine on passing a single parameter, What changes do i need to recieve both the parameters value.
Currently its giving me error at:
deepLink?.getQueryParameter("meetingCode")?.let { joinMeeting(it) }
No value passed for parameter 'meetingToken'
Link = https://example.in/?meetingCode=myuser?meetingToken=rtgdhh.tywufgsioqpp
private fun handleDynamicLink() {
Firebase.dynamicLinks
.getDynamicLink(intent)
.addOnSuccessListener { pendingDynamicLinkData ->
val deepLink: Uri?
if (pendingDynamicLinkData != null) {
deepLink = pendingDynamicLinkData.link
on android debugging its generating the following firebase Link = https://example.in/?meetingCode=userroom?meetingToken%3DeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1Ni
deepLink?.getQueryParameter("meetingToken")
deepLink?.getQueryParameter("meetingCode")?.let { joinMeeting(it) }
}
}
.addOnFailureListener { _ ->
toast(getString(R.string.main_error_fetch_dynamic_link))
}
}
private fun joinMeeting (meetingCode:String, meetingToken:String) {
MeetingUtils.startMeeting(
this, meetingCode,
meetingToken)
}
meeting Utils.kt file to start meeting
object MeetingUtils {
fun startMeeting(context: Context, meetingCode: String, meetingToken: String)
app deep link url string
<string name="app_deep_link_url">https://example.in/?meetingCode=%1$s?meetingToken=%2$s</string>
this is the share code
private fun onShareMeetingCodeClick() {
tilCodeCreateMeeting.setEndIconOnClickListener {
binding.tilCodeCreateMeeting.error = null
toast(getString(R.string.main_creating_dynamic_link))
Firebase.dynamicLinks.shortLinkAsync {
link = Uri.parse(getString(R.string.app_deep_link_url, getCreateMeetingCode(), getCreateMeetingToken() ))
domainUriPrefix = getString(R.string.app_dynamic_link_url_prefix)
androidParameters {}
navigationInfoParameters {
forcedRedirectEnabled = true // Directly open the link in the app
}
}.addOnSuccessListener { result ->
val shortDynamicLink = result.shortLink.toString()
startShareTextIntent(
getString(R.string.main_share_meeting_code_title),
getString(R.string.main_share_meeting_code_desc, shortDynamicLink)
)
}.addOnFailureListener {
toast(getString(R.string.main_error_create_dynamic_link))
}
Can Someone guide me how to recieve value of getQueryparameter for more than 1 parameter. Thanks in Advance

You should use & instead of ? on appending the second parameter on your deep link. Also, the deep link configured should be URL-encoded since multiple parameters are configured in the deep link. Your sample deep link should look like this.
link=https%3A%2F%2Fexample.in%2F%3FmeetingCode%3Dmyuser%26meetingToken%3Drtgdhh.tywufgsioqpp
By URL-encoding the deep link, FDL will able to distinguish which parameters belongs to the deep link.
Uri.parse(getString(R.string.app_deep_link_url, getCreateMeetingCode(), getCreateMeetingToken()))
I'm not sure on what you're trying to achieve passing multiple parameters on getString for the deep link value.
Won't it make sense to create a StringBuilder or append it manually?
val deepLink = getString(R.string.app_deep_link_url)+ "%2F%3FmeetingCode%3D$meetingCode%26meetingToken%3D$meetingToken";
link = Uri.parse(deepLink);
where "app_deep_link_url" in strings.xml is
<string name="app_deep_link_url">https%3A%2F%2Fexample.in</string>

Related

Is there any way to get firebaesevisionimagelabel data in oncreate?

Im trying to make copy of firebasevisionimagelabel, but only it works in function after then i can't get any of label in oncreate
This is firebase,written in kotlin. i've put string in wordpilec but i can't load it in oncreate
private fun runDetector (bitmap : Bitmap?){
val image = FirebaseVisionImage.fromBitmap(bitmap!!)
val options = FirebaseVisionCloudImageLabelerOptions.Builder()
.setConfidenceThreshold(0.7f)
.build()
val labeler = FirebaseVision.getInstance().getCloudImageLabeler(options)
labeler.processImage(image)
.addOnSuccessListener { labels -> processResultfromcloud(labels)
}
private fun processResultfromcloud(labels: List<FirebaseVisionImageLabel>) {
for (label in labels) {
builder.append(label.text).append(",")
}
wordpilec = builder.toString()
stringtoArray(wordpilec)
}
I expect strings should be same but one is null the other is perfect . I can not get perfect one
The detector runs asynchronously, and I'm guessing you are trying to access wordpilec in onCreate before the detector has assigned a value assigned to it. You could try and move the operation you are trying to do with the string to the success listener instead.

Changelog method based on project tracker template

Based on the project tracker I have integrated a changelog into my app that relates my UserSettings model to a UserHistory model. The latter contains the fields FieldName, CreatedBy, CreatedDate, OldValue, NewValue.
The relation between both models works fine. Whenever a record is modified, I can see the changes in a changelog table. I now want add an "undo"-button to the table that allows the admin to undo a change he clicks on. I have therefore created a method that is handled by the widget that holds the changelog record:
function undoChangesToUserRecord(changelog) {
if (!isAdmin()) {
return;
}
var fieldName = changelog.datasource.item.FieldName;
var record = changelog.datasource.item.UserSettings;
record[fieldName] = changelog.datasource.item.OldValue;
}
In theory method goes the connection between UserHistory and UserSettings up to the field and rewrites its value. But when I click on the button, I get a "Failed due to circular reference" error. What am I doing wrong?
I was able to repro the issue with this bit of code:
google.script.run.ServerFunction(app.currentPage.descendants.SomeWidget);
It is kinda expected behavior, because all App Maker objects are pretty much complex and Apps Script RPC has some limitations.
App Maker way to implement it would look like this:
// Server side script
function undoChangesToUserRecord(key) {
if (!isAdmin()) {
return;
}
var history = app.models.UserHistory.getRecord(key);
if (history !== null) {
var fieldName = history.FieldName;
var settings = history.UserSettings;
settings[fieldName] = history.OldValue;
}
}
// Client side script
function onUndoClick(button) {
var history = widget.datasource.item;
google.script.run
.undoChangesToUserRecord(history._key);
}

FROM Http Header not included unless it's a valid email address

I'm using the Advanced Rest Client Chrome extension to test a request to a Web API 2 endpoint. I'm trying to include a value in the "From" header but the value is null when it is not a valid email address. By reading the spec, it looks like it only SHOULD be a valid email address, not that it MUST. Is this something that is happening because of Web API, Chrome, the extension, or something else?
After your comment about Fiddler seeing the header, I was curious so I did a little test. Here is my controller code:
public class FromController : ApiController
{
[Route("api/from")]
public dynamic Get()
{
string from1 = null;
string from2 = null;
string from3 = null;
from1 = this.Request.Headers.From;
IEnumerable<string> headers;
if (this.Request.Headers.TryGetValues("From", out headers))
{
from2 = headers.FirstOrDefault();
}
if (HttpContext.Current.Request.Headers.AllKeys.Contains("From"))
{
from3 = HttpContext.Current.Request.Headers["From"];
}
var output = new
{
From1 = from1,
From2 = from2,
From3 = from3
};
return output;
}
}
Test 1: Send e#test.com as the From header outputs:
{
"From1": "e#test.com",
"From2": "e#test.com",
"From3": "e#test.com"
}
Everything is as expected.
Test 2: Send junk as the From header outputs:
{
"From1": null,
"From2": "junk",
"From3": "junk"
}
This shows your findings of the header being null, but you can get it via the other methods.
Internally it's running some parsing on the values. The value is stored in an invalid container so asking for it directly results in null. By asking via TryGetValue, it ignores any "helpful" parsing so you'll get the value.
I added the old HttpContext.Current.Request just to see since this is more raw form, but I'd steer clear from using this in production and try to stick with this.Request for anything while in a Controller. I like to use HttpContext.Current.Request.SaveAs(fileName, true) to see what the actual raw request is. I did this first and saw the header so I knew it had to be accessible somehow.

Cannot implicitly convert type 'System.Linq.IQueryable to System.Data.Entity.DbSet<>

I receive the following error when I try to run my code. I haven't managed to solve it yet, please Help:
edit: Marked with * where it fails.
>
public IQueryable<Video> GetVideos([QueryString("id")] int? categorieId)
{
var _db = new TeleviziuneAcademicaAspSilverlight.Models.VideoContext();
IQueryable<Video> query = *_db.Videos;*
if (categorieId.HasValue && categorieId > 0)
{
query = query.Where(v => v.CategorieID == categorieId);
}
return query;
Change
IQueryable<Video> query =
to
IQueryable<Appname.Models.Video> query =
The reason for your error is that you have the type Video defined twice and because of using a short type name you accidentally reference not the one Video you should.
Also change it in the method's return value
public IQueryable<Appname.Models.Video> GetVideos( ... )
You seem to have two classes called Video. If you need both, you'll need to project from one to the other before your return statement:
return query.Select(dbVideo => new Appname.Video()
{
Prop1 = dbVideo.Prop1,
Prop2 = dbVideo.Prop2,
// etc.
});
Though you'll probably need to change the return type to an IEnumerable<> if you do that.
If you can just work with Appname.Models.Video, change IQueryable<Video> to IQueryable<Appname.Models.Video> in the method signature and the method body.

Multiple TrackingParticipants not working, have funny side effects?

We are rying to use WF with multiple tracking participants which essentially listen to different queries - one for activity states, one for custom tracknig records which are a subclass of CustomTrackingRecord.
The problem is that we can use both TrackingParticipants indivisually, but not together - we never get our subclass from CustomTrackingRecord but A CustomTrackingRecord.
If I put bopth queries into one TrackingParticipant and then handle everythign in one, both work perfectly (which indicates teh error is not where we throw them).
The code in question for the combined one is:
public WorkflowServiceTrackingParticipant ()
{
this.TrackingProfile = new TrackingProfile()
{
ActivityDefinitionId = "*",
ImplementationVisibility = ImplementationVisibility.All,
Name = "WorkflowServiceTrackingProfile",
Queries = {
new CustomTrackingQuery() { Name = "*", ActivityName = "*" },
new ActivityStateQuery() {
States = {
ActivityStates.Canceled,
ActivityStates.Closed,
ActivityStates.Executing,
ActivityStates.Faulted
}
},
}
};
}
When using two TrackingParticipants we have two TrackingProfile (with different names) that each have one of the queries.
in the track method, when using both separate, the lines:
protected override void Track(TrackingRecord record, TimeSpan timeout)
{
Console.WriteLine("*** ActivityTracking: " + record.GetType());
if (record is ActivityBasedTrackingRecord)
{
System.Diagnostics.Debugger.Break();
}
never result in the debugger hitting, when using only the one to track our CustomTrackingRecord subclass (ActivityBasedTrackingRecord) then it works.
Anyone else knows about this? For now we have combined both TrackingParticipants into one, but this has the bad side effect that we can not dynamically expand the logging possibilities, which we would love to. Is this a known issue with WWF somewhere?
Version used: 4.0 Sp1 Feature Update 1.
I guess I encounterad the exact same problem.
This problem occurs due to the restrictions of the extension mechanism. There can be only one instance per extension type per workflow instance (according to Microsoft's documentation). Interesting enough though, one can add multiple instances of the same type to one workflow's extensions which - in case of TrackingParticipant derivates - causes weird behavior, because only one of their tracking profiles is used for all participants of the respective type, but all their overrides of the Track method are getting invoked.
There is a (imho) ugly workaround to this: derive a new participant class from TrackingParticipant for each task (task1, task2, logging ...)
Regards,
Jacob
I think that this problem isn't caused by extension mechanism, since DerivedParticipant 1 and DerivedParticipant 2 are not the same type(WF internals just use polymorphism on the base class).
I was running on the same issue, my Derived1 was tracking records that weren't described in its profile.
Derived1.TrackingProfile.Name was "Foo" and Derived2.TrackingProfile.Name was null
I changed the name from null to "Bar" and it worked as expected.
Here is a WF internal reference code, describing how is the Profile selected
// System.Activities.Tracking.RuntimeTrackingProfile.RuntimeTrackingProfileCache
public RuntimeTrackingProfile GetRuntimeTrackingProfile(TrackingProfile profile, Activity rootElement)
{
RuntimeTrackingProfile runtimeTrackingProfile = null;
HybridCollection<RuntimeTrackingProfile> hybridCollection = null;
lock (this.cache)
{
if (!this.cache.TryGetValue(rootElement, out hybridCollection))
{
runtimeTrackingProfile = new RuntimeTrackingProfile(profile, rootElement);
hybridCollection = new HybridCollection<RuntimeTrackingProfile>();
hybridCollection.Add(runtimeTrackingProfile);
this.cache.Add(rootElement, hybridCollection);
}
else
{
ReadOnlyCollection<RuntimeTrackingProfile> readOnlyCollection = hybridCollection.AsReadOnly();
foreach (RuntimeTrackingProfile current in readOnlyCollection)
{
if (string.CompareOrdinal(profile.Name, current.associatedProfile.Name) == 0 && string.CompareOrdinal(profile.ActivityDefinitionId, current.associatedProfile.ActivityDefinitionId) == 0)
{
runtimeTrackingProfile = current;
break;
}
}
if (runtimeTrackingProfile == null)
{
runtimeTrackingProfile = new RuntimeTrackingProfile(profile, rootElement);
hybridCollection.Add(runtimeTrackingProfile);
}
}
}
return runtimeTrackingProfile;
}

Resources